mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Modify route _processor list set up so that the logic for placing `invisible' processors (e.g. internal returns etc.) is in one place. Add option to get pre-fade listen from before or after pre-fade processors (#3781).
git-svn-id: svn://localhost/ardour2/branches/3.0@8903 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c77d116703
commit
13232d03f3
13 changed files with 326 additions and 213 deletions
|
|
@ -4870,8 +4870,6 @@ Editor::handle_new_route (RouteList& routes)
|
||||||
RouteTimeAxisView *rtv;
|
RouteTimeAxisView *rtv;
|
||||||
list<RouteTimeAxisView*> new_views;
|
list<RouteTimeAxisView*> new_views;
|
||||||
|
|
||||||
cerr << "Handle new route\n";
|
|
||||||
|
|
||||||
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||||
boost::shared_ptr<Route> route = (*x);
|
boost::shared_ptr<Route> route = (*x);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@ EditorRoutes::on_tv_solo_enable_toggled (std::string const & path_string)
|
||||||
boost::shared_ptr<RouteList> rl (new RouteList);
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
||||||
rl->push_back (rtv->route());
|
rl->push_back (rtv->route());
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
_session->set_listen (rl, !rtv->route()->listening(), Session::rt_cleanup);
|
_session->set_listen (rl, !rtv->route()->listening_via_monitor(), Session::rt_cleanup);
|
||||||
} else {
|
} else {
|
||||||
_session->set_solo (rl, !rtv->route()->self_soloed(), Session::rt_cleanup);
|
_session->set_solo (rl, !rtv->route()->self_soloed(), Session::rt_cleanup);
|
||||||
}
|
}
|
||||||
|
|
@ -929,7 +929,7 @@ EditorRoutes::key_press (GdkEventKey* ev)
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
_session->set_listen (rl, !rl->front()->listening(), Session::rt_cleanup);
|
_session->set_listen (rl, !rl->front()->listening_via_monitor(), Session::rt_cleanup);
|
||||||
} else {
|
} else {
|
||||||
_session->set_solo (rl, !rl->front()->self_soloed(), Session::rt_cleanup);
|
_session->set_solo (rl, !rl->front()->self_soloed(), Session::rt_cleanup);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -553,8 +553,8 @@ GainMeterBase::meter_press(GdkEventButton* ev)
|
||||||
gint
|
gint
|
||||||
GainMeterBase::meter_release(GdkEventButton*)
|
GainMeterBase::meter_release(GdkEventButton*)
|
||||||
{
|
{
|
||||||
if(!ignore_toggle){
|
if (!ignore_toggle) {
|
||||||
if (wait_for_release){
|
if (wait_for_release) {
|
||||||
wait_for_release = false;
|
wait_for_release = false;
|
||||||
|
|
||||||
if (_route) {
|
if (_route) {
|
||||||
|
|
|
||||||
|
|
@ -1090,6 +1090,18 @@ RCOptionEditor::RCOptionEditor ()
|
||||||
mm->add (ExternalMonitoring, _("audio hardware"));
|
mm->add (ExternalMonitoring, _("audio hardware"));
|
||||||
|
|
||||||
add_option (_("Audio"), mm);
|
add_option (_("Audio"), mm);
|
||||||
|
|
||||||
|
ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
|
||||||
|
"pfl-position",
|
||||||
|
_("PFL signals come from"),
|
||||||
|
sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
|
||||||
|
sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
|
||||||
|
);
|
||||||
|
|
||||||
|
pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
|
||||||
|
pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
|
||||||
|
|
||||||
|
add_option (_("Audio"), pp);
|
||||||
|
|
||||||
add_option (_("Audio"),
|
add_option (_("Audio"),
|
||||||
new BoolOption (
|
new BoolOption (
|
||||||
|
|
|
||||||
|
|
@ -408,7 +408,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
_session->set_listen (_session->get_routes(), !_route->listening(), Session::rt_cleanup, true);
|
_session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, true);
|
||||||
} else {
|
} else {
|
||||||
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, true);
|
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, true);
|
||||||
}
|
}
|
||||||
|
|
@ -458,7 +458,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
_session->set_listen (_route->route_group()->route_list(), !_route->listening(), Session::rt_cleanup, true);
|
_session->set_listen (_route->route_group()->route_list(), !_route->listening_via_monitor(), Session::rt_cleanup, true);
|
||||||
} else {
|
} else {
|
||||||
_session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(), Session::rt_cleanup, true);
|
_session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(), Session::rt_cleanup, true);
|
||||||
}
|
}
|
||||||
|
|
@ -476,7 +476,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
_session->set_listen (rl, !_route->listening());
|
_session->set_listen (rl, !_route->listening_via_monitor());
|
||||||
} else {
|
} else {
|
||||||
_session->set_solo (rl, !_route->self_soloed());
|
_session->set_solo (rl, !_route->self_soloed());
|
||||||
}
|
}
|
||||||
|
|
@ -816,7 +816,7 @@ RouteUI::solo_visual_state (boost::shared_ptr<Route> r)
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
|
|
||||||
if (r->listening()) {
|
if (r->listening_via_monitor()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -844,7 +844,7 @@ RouteUI::solo_visual_state_with_isolate (boost::shared_ptr<Route> r)
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
|
|
||||||
if (r->listening()) {
|
if (r->listening_via_monitor()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -900,7 +900,7 @@ RouteUI::update_solo_display ()
|
||||||
|
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
|
|
||||||
if (solo_button->get_active() != (x = _route->listening())) {
|
if (solo_button->get_active() != (x = _route->listening_via_monitor())) {
|
||||||
++_i_am_the_modifier;
|
++_i_am_the_modifier;
|
||||||
solo_button->set_active(x);
|
solo_button->set_active(x);
|
||||||
--_i_am_the_modifier;
|
--_i_am_the_modifier;
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", t
|
||||||
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
|
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
|
||||||
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
|
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
|
||||||
CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
|
CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
|
||||||
|
CONFIG_VARIABLE (PFLPosition, pfl_position, "pfl-position", PFLFromAfterProcessors)
|
||||||
CONFIG_VARIABLE (bool, use_monitor_bus, "use-monitor-bus", false)
|
CONFIG_VARIABLE (bool, use_monitor_bus, "use-monitor-bus", false)
|
||||||
|
|
||||||
CONFIG_VARIABLE (bool, solo_control_is_listen_control, "solo-control-is-listen-control", false)
|
CONFIG_VARIABLE (bool, solo_control_is_listen_control, "solo-control-is-listen-control", false)
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||||
bool solo_safe() const;
|
bool solo_safe() const;
|
||||||
|
|
||||||
void set_listen (bool yn, void* src);
|
void set_listen (bool yn, void* src);
|
||||||
bool listening () const;
|
bool listening_via_monitor () const;
|
||||||
|
|
||||||
void set_phase_invert (uint32_t, bool yn);
|
void set_phase_invert (uint32_t, bool yn);
|
||||||
void set_phase_invert (boost::dynamic_bitset<>);
|
void set_phase_invert (boost::dynamic_bitset<>);
|
||||||
|
|
@ -220,7 +220,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||||
void add_internal_return ();
|
void add_internal_return ();
|
||||||
BufferSet* get_return_buffer () const;
|
BufferSet* get_return_buffer () const;
|
||||||
void release_return_buffer () const;
|
void release_return_buffer () const;
|
||||||
void put_monitor_send_at (Placement);
|
void listen_position_changed ();
|
||||||
boost::shared_ptr<CapturingProcessor> add_export_point(/* Add some argument for placement later */);
|
boost::shared_ptr<CapturingProcessor> add_export_point(/* Add some argument for placement later */);
|
||||||
|
|
||||||
/** A record of the stream configuration at some point in the processor list.
|
/** A record of the stream configuration at some point in the processor list.
|
||||||
|
|
@ -294,7 +294,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||||
|
|
||||||
PBD::Signal1<void,void*> SelectedChanged;
|
PBD::Signal1<void,void*> SelectedChanged;
|
||||||
|
|
||||||
int listen_via (boost::shared_ptr<Route>, Placement p, bool active, bool aux);
|
int listen_via_monitor ();
|
||||||
|
int listen_via (boost::shared_ptr<Route>, Placement p);
|
||||||
void drop_listen (boost::shared_ptr<Route>);
|
void drop_listen (boost::shared_ptr<Route>);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -508,6 +509,40 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||||
|
|
||||||
void set_processor_positions ();
|
void set_processor_positions ();
|
||||||
void update_port_latencies (const PortSet& ports, const PortSet& feeders, bool playback, framecnt_t) const;
|
void update_port_latencies (const PortSet& ports, const PortSet& feeders, bool playback, framecnt_t) const;
|
||||||
|
|
||||||
|
void setup_invisible_processors ();
|
||||||
|
|
||||||
|
boost::shared_ptr<CapturingProcessor> _capturing_processor;
|
||||||
|
|
||||||
|
/** A handy class to keep processor state while we attempt a reconfiguration
|
||||||
|
* that may fail.
|
||||||
|
*/
|
||||||
|
class ProcessorState {
|
||||||
|
public:
|
||||||
|
ProcessorState (Route* r)
|
||||||
|
: _route (r)
|
||||||
|
, _processors (r->_processors)
|
||||||
|
, _processor_max_streams (r->processor_max_streams)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void restore () {
|
||||||
|
_route->_processors = _processors;
|
||||||
|
_route->processor_max_streams = _processor_max_streams;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* this should perhaps be a shared_ptr, but ProcessorStates will
|
||||||
|
not hang around long enough for it to matter.
|
||||||
|
*/
|
||||||
|
Route* _route;
|
||||||
|
ProcessorList _processors;
|
||||||
|
ChanCount _processor_max_streams;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class ProcessorState;
|
||||||
|
|
||||||
|
/* no copy construction */
|
||||||
|
Route (Route const &);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,13 @@ namespace ARDOUR {
|
||||||
ExternalMonitoring
|
ExternalMonitoring
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PFLPosition {
|
||||||
|
/** PFL signals come from before pre-fader processors */
|
||||||
|
PFLFromBeforeProcessors,
|
||||||
|
/** PFL signals come pre-fader but after pre-fader processors */
|
||||||
|
PFLFromAfterProcessors
|
||||||
|
};
|
||||||
|
|
||||||
enum DenormalModel {
|
enum DenormalModel {
|
||||||
DenormalNone,
|
DenormalNone,
|
||||||
DenormalFTZ,
|
DenormalFTZ,
|
||||||
|
|
@ -557,6 +564,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf);
|
||||||
|
std::istream& operator>>(std::istream& o, ARDOUR::PFLPosition& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::ListenPosition& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::ListenPosition& sf);
|
||||||
std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf);
|
std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf);
|
||||||
|
|
@ -576,6 +584,7 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoConnectOption& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoConnectOption& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::EditMode& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::EditMode& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::MonitorModel& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::MonitorModel& sf);
|
||||||
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::PFLPosition& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::RemoteModel& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::RemoteModel& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::ListenPosition& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::ListenPosition& sf);
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::LayerModel& sf);
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::LayerModel& sf);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ setup_enum_writer ()
|
||||||
RegionPoint _RegionPoint;
|
RegionPoint _RegionPoint;
|
||||||
Placement _Placement;
|
Placement _Placement;
|
||||||
MonitorModel _MonitorModel;
|
MonitorModel _MonitorModel;
|
||||||
|
PFLPosition _PFLPosition;
|
||||||
RemoteModel _RemoteModel;
|
RemoteModel _RemoteModel;
|
||||||
DenormalModel _DenormalModel;
|
DenormalModel _DenormalModel;
|
||||||
CrossfadeModel _CrossfadeModel;
|
CrossfadeModel _CrossfadeModel;
|
||||||
|
|
@ -219,6 +220,10 @@ setup_enum_writer ()
|
||||||
REGISTER_ENUM (ExternalMonitoring);
|
REGISTER_ENUM (ExternalMonitoring);
|
||||||
REGISTER (_MonitorModel);
|
REGISTER (_MonitorModel);
|
||||||
|
|
||||||
|
REGISTER_ENUM (PFLFromBeforeProcessors);
|
||||||
|
REGISTER_ENUM (PFLFromAfterProcessors);
|
||||||
|
REGISTER (_PFLPosition);
|
||||||
|
|
||||||
REGISTER_ENUM (DenormalNone);
|
REGISTER_ENUM (DenormalNone);
|
||||||
REGISTER_ENUM (DenormalFTZ);
|
REGISTER_ENUM (DenormalFTZ);
|
||||||
REGISTER_ENUM (DenormalDAZ);
|
REGISTER_ENUM (DenormalDAZ);
|
||||||
|
|
@ -603,6 +608,7 @@ std::ostream& operator<<(std::ostream& o, const AutoConnectOption& var)
|
||||||
std::string s = enum_2_string (var);
|
std::string s = enum_2_string (var);
|
||||||
return o << s;
|
return o << s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& operator>>(std::istream& o, MonitorModel& var)
|
std::istream& operator>>(std::istream& o, MonitorModel& var)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
@ -616,6 +622,21 @@ std::ostream& operator<<(std::ostream& o, const MonitorModel& var)
|
||||||
std::string s = enum_2_string (var);
|
std::string s = enum_2_string (var);
|
||||||
return o << s;
|
return o << s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::istream& operator>>(std::istream& o, PFLPosition& var)
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
o >> s;
|
||||||
|
var = (PFLPosition) string_2_enum (s, var);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& o, const PFLPosition& var)
|
||||||
|
{
|
||||||
|
std::string s = enum_2_string (var);
|
||||||
|
return o << s;
|
||||||
|
}
|
||||||
|
|
||||||
std::istream& operator>>(std::istream& o, RemoteModel& var)
|
std::istream& operator>>(std::istream& o, RemoteModel& var)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ MonitorProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /
|
||||||
target_gain = 0.0;
|
target_gain = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_gain != _channels[chn]->current_gain || target_gain != 1.0f) {
|
if (target_gain != _channels[chn]->current_gain || target_gain != 1.0f) {
|
||||||
|
|
||||||
Amp::apply_gain (*b, nframes, _channels[chn]->current_gain, target_gain);
|
Amp::apply_gain (*b, nframes, _channels[chn]->current_gain, target_gain);
|
||||||
|
|
@ -334,7 +334,8 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out)
|
||||||
bool
|
bool
|
||||||
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||||
{
|
{
|
||||||
return in == out;
|
out = in;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -144,37 +144,27 @@ Route::init ()
|
||||||
_amp.reset (new Amp (_session));
|
_amp.reset (new Amp (_session));
|
||||||
add_processor (_amp, PostFader);
|
add_processor (_amp, PostFader);
|
||||||
|
|
||||||
/* add standard processors: meter, main outs, monitor out */
|
/* create standard processors: meter, main outs, monitor out;
|
||||||
|
they will be added to _processors by setup_invisible_processors ()
|
||||||
|
*/
|
||||||
|
|
||||||
_meter.reset (new PeakMeter (_session));
|
_meter.reset (new PeakMeter (_session));
|
||||||
_meter->set_display_to_user (false);
|
_meter->set_display_to_user (false);
|
||||||
|
_meter->activate ();
|
||||||
add_processor (_meter, PostFader);
|
|
||||||
|
|
||||||
_main_outs.reset (new Delivery (_session, _output, _pannable, _mute_master, _name, Delivery::Main));
|
_main_outs.reset (new Delivery (_session, _output, _pannable, _mute_master, _name, Delivery::Main));
|
||||||
|
_main_outs->activate ();
|
||||||
add_processor (_main_outs, PostFader);
|
|
||||||
|
|
||||||
if (is_monitor()) {
|
if (is_monitor()) {
|
||||||
/* where we listen to tracks */
|
/* where we listen to tracks */
|
||||||
_intreturn.reset (new InternalReturn (_session));
|
_intreturn.reset (new InternalReturn (_session));
|
||||||
add_processor (_intreturn, PreFader);
|
_intreturn->activate ();
|
||||||
|
|
||||||
ProcessorList::iterator i;
|
|
||||||
|
|
||||||
for (i = _processors.begin(); i != _processors.end(); ++i) {
|
|
||||||
if (*i == _intreturn) {
|
|
||||||
++i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the thing that provides proper control over a control/monitor/listen bus
|
/* the thing that provides proper control over a control/monitor/listen bus
|
||||||
(such as per-channel cut, dim, solo, invert, etc).
|
(such as per-channel cut, dim, solo, invert, etc).
|
||||||
It always goes right after the internal return;
|
|
||||||
*/
|
*/
|
||||||
_monitor_control.reset (new MonitorProcessor (_session));
|
_monitor_control.reset (new MonitorProcessor (_session));
|
||||||
add_processor (_monitor_control, i);
|
_monitor_control->activate ();
|
||||||
|
|
||||||
/* no panning on the monitor main outs */
|
/* no panning on the monitor main outs */
|
||||||
|
|
||||||
|
|
@ -191,6 +181,12 @@ Route::init ()
|
||||||
|
|
||||||
Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
|
Metering::Meter.connect_same_thread (*this, (boost::bind (&Route::meter, this)));
|
||||||
|
|
||||||
|
{
|
||||||
|
/* run a configure so that the invisible processors get set up */
|
||||||
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
configure_processors (0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,7 +501,7 @@ Route::process_output_buffers (BufferSet& bufs,
|
||||||
if (boost::dynamic_pointer_cast<UnknownProcessor> (*i)) {
|
if (boost::dynamic_pointer_cast<UnknownProcessor> (*i)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufs.count() != (*i)->input_streams()) {
|
if (bufs.count() != (*i)->input_streams()) {
|
||||||
cerr << _name << " bufs = " << bufs.count()
|
cerr << _name << " bufs = " << bufs.count()
|
||||||
<< " input for " << (*i)->name() << " = " << (*i)->input_streams()
|
<< " input for " << (*i)->name() << " = " << (*i)->input_streams()
|
||||||
|
|
@ -600,7 +596,7 @@ Route::set_listen (bool yn, void* src)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Route::listening () const
|
Route::listening_via_monitor () const
|
||||||
{
|
{
|
||||||
if (_monitor_send) {
|
if (_monitor_send) {
|
||||||
return _monitor_send->active ();
|
return _monitor_send->active ();
|
||||||
|
|
@ -862,13 +858,14 @@ Route::add_processor (boost::shared_ptr<Processor> processor, Placement placemen
|
||||||
|
|
||||||
|
|
||||||
/** Add a processor to the route.
|
/** Add a processor to the route.
|
||||||
* @a iter must point to an iterator in _processors and the new
|
* @param iter an iterator in _processors; the new processor will be inserted immediately before this location.
|
||||||
* processor will be inserted immediately before this location. Otherwise,
|
|
||||||
* @a position is used.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err, bool activation_allowed)
|
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err, bool activation_allowed)
|
||||||
{
|
{
|
||||||
|
assert (processor != _meter);
|
||||||
|
assert (processor != _main_outs);
|
||||||
|
|
||||||
ChanCount old_pms = processor_max_streams;
|
ChanCount old_pms = processor_max_streams;
|
||||||
|
|
||||||
if (!_session.engine().connected() || !processor) {
|
if (!_session.engine().connected() || !processor) {
|
||||||
|
|
@ -877,14 +874,15 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
|
ProcessorState pstate (this);
|
||||||
|
|
||||||
boost::shared_ptr<PluginInsert> pi;
|
boost::shared_ptr<PluginInsert> pi;
|
||||||
boost::shared_ptr<PortInsert> porti;
|
boost::shared_ptr<PortInsert> porti;
|
||||||
|
|
||||||
ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
|
ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), processor);
|
||||||
|
|
||||||
if (processor == _amp || processor == _meter || processor == _main_outs) {
|
if (processor == _amp) {
|
||||||
// Ensure only one of these are in the list at any time
|
// Ensure only one amp is in the list at any time
|
||||||
if (loc != _processors.end()) {
|
if (loc != _processors.end()) {
|
||||||
if (iter == loc) { // Already in place, do nothing
|
if (iter == loc) { // Already in place, do nothing
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -911,9 +909,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
|
||||||
if (configure_processors_unlocked (err)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
ProcessorList::iterator ploc = loc;
|
pstate.restore ();
|
||||||
--ploc;
|
|
||||||
_processors.erase(ploc);
|
|
||||||
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
||||||
cerr << "configure failed\n";
|
cerr << "configure failed\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -929,15 +925,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is this the monitor send ? if so, make sure we keep track of it */
|
if (activation_allowed) {
|
||||||
|
|
||||||
boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (processor);
|
|
||||||
|
|
||||||
if (isend && _session.monitor_out() && (isend->target_id() == _session.monitor_out()->id())) {
|
|
||||||
_monitor_send = isend;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activation_allowed && (processor != _monitor_send)) {
|
|
||||||
processor->activate ();
|
processor->activate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1033,8 +1021,8 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
|
||||||
if (before) {
|
if (before) {
|
||||||
loc = find(_processors.begin(), _processors.end(), before);
|
loc = find(_processors.begin(), _processors.end(), before);
|
||||||
} else {
|
} else {
|
||||||
/* nothing specified - at end but before main outs */
|
/* nothing specified - at end */
|
||||||
loc = find (_processors.begin(), _processors.end(), _main_outs);
|
loc = _processors.end ();
|
||||||
}
|
}
|
||||||
|
|
||||||
ChanCount old_pms = processor_max_streams;
|
ChanCount old_pms = processor_max_streams;
|
||||||
|
|
@ -1049,29 +1037,18 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
|
ProcessorState pstate (this);
|
||||||
ChanCount potential_max_streams = ChanCount::max (_input->n_ports(), _output->n_ports());
|
|
||||||
|
|
||||||
for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
|
for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
|
||||||
|
|
||||||
// Ensure meter only appears in the list once
|
|
||||||
if (*i == _meter) {
|
if (*i == _meter) {
|
||||||
ProcessorList::iterator m = find(_processors.begin(), _processors.end(), *i);
|
continue;
|
||||||
if (m != _processors.end()) {
|
|
||||||
_processors.erase(m);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<PluginInsert> pi;
|
boost::shared_ptr<PluginInsert> pi;
|
||||||
|
|
||||||
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
||||||
pi->set_count (1);
|
pi->set_count (1);
|
||||||
|
|
||||||
ChanCount m = max (pi->input_streams(), pi->output_streams());
|
|
||||||
|
|
||||||
if (m > potential_max_streams) {
|
|
||||||
potential_max_streams = m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessorList::iterator inserted = _processors.insert (loc, *i);
|
ProcessorList::iterator inserted = _processors.insert (loc, *i);
|
||||||
|
|
@ -1083,7 +1060,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
if (configure_processors_unlocked (err)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
_processors.erase (inserted);
|
pstate.restore ();
|
||||||
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1327,6 +1304,8 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
|
ProcessorState pstate (this);
|
||||||
|
|
||||||
ProcessorList::iterator i;
|
ProcessorList::iterator i;
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
|
|
||||||
|
|
@ -1373,8 +1352,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
|
||||||
if (configure_processors_unlocked (err)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
/* get back to where we where */
|
pstate.restore ();
|
||||||
_processors.insert (i, processor);
|
|
||||||
/* we know this will work, because it worked before :) */
|
/* we know this will work, because it worked before :) */
|
||||||
configure_processors_unlocked (0);
|
configure_processors_unlocked (0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -1415,11 +1393,11 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
|
ProcessorState pstate (this);
|
||||||
|
|
||||||
ProcessorList::iterator i;
|
ProcessorList::iterator i;
|
||||||
boost::shared_ptr<Processor> processor;
|
boost::shared_ptr<Processor> processor;
|
||||||
|
|
||||||
ProcessorList as_we_were = _processors;
|
|
||||||
|
|
||||||
for (i = _processors.begin(); i != _processors.end(); ) {
|
for (i = _processors.begin(); i != _processors.end(); ) {
|
||||||
|
|
||||||
processor = *i;
|
processor = *i;
|
||||||
|
|
@ -1464,8 +1442,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
|
||||||
if (configure_processors_unlocked (err)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
/* get back to where we where */
|
pstate.restore ();
|
||||||
_processors = as_we_were;
|
|
||||||
/* we know this will work, because it worked before :) */
|
/* we know this will work, because it worked before :) */
|
||||||
configure_processors_unlocked (0);
|
configure_processors_unlocked (0);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -1508,6 +1485,7 @@ Route::configure_processors (ProcessorStreams* err)
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
return configure_processors_unlocked (err);
|
return configure_processors_unlocked (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1577,6 +1555,9 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* put invisible processors where they should be */
|
||||||
|
setup_invisible_processors ();
|
||||||
|
|
||||||
_in_configure_processors = true;
|
_in_configure_processors = true;
|
||||||
|
|
||||||
list<pair<ChanCount, ChanCount> > configuration = try_configure_processors_unlocked (input_streams (), err);
|
list<pair<ChanCount, ChanCount> > configuration = try_configure_processors_unlocked (input_streams (), err);
|
||||||
|
|
@ -1706,10 +1687,10 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
ChanCount old_pms = processor_max_streams;
|
ProcessorState pstate (this);
|
||||||
|
|
||||||
ProcessorList::iterator oiter;
|
ProcessorList::iterator oiter;
|
||||||
ProcessorList::const_iterator niter;
|
ProcessorList::const_iterator niter;
|
||||||
ProcessorList as_it_was_before = _processors;
|
|
||||||
ProcessorList as_it_will_be;
|
ProcessorList as_it_will_be;
|
||||||
|
|
||||||
oiter = _processors.begin();
|
oiter = _processors.begin();
|
||||||
|
|
@ -1767,8 +1748,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
|
||||||
if (configure_processors_unlocked (err)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
_processors = as_it_was_before;
|
pstate.restore ();
|
||||||
processor_max_streams = old_pms;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2348,24 +2328,20 @@ Route::set_processor_state (const XMLNode& node)
|
||||||
new_order.push_back (_amp);
|
new_order.push_back (_amp);
|
||||||
} else if (prop->value() == "meter") {
|
} else if (prop->value() == "meter") {
|
||||||
_meter->set_state (**niter, Stateful::current_state_version);
|
_meter->set_state (**niter, Stateful::current_state_version);
|
||||||
new_order.push_back (_meter);
|
|
||||||
} else if (prop->value() == "main-outs") {
|
} else if (prop->value() == "main-outs") {
|
||||||
_main_outs->set_state (**niter, Stateful::current_state_version);
|
_main_outs->set_state (**niter, Stateful::current_state_version);
|
||||||
new_order.push_back (_main_outs);
|
|
||||||
} else if (prop->value() == "intreturn") {
|
} else if (prop->value() == "intreturn") {
|
||||||
if (!_intreturn) {
|
if (!_intreturn) {
|
||||||
_intreturn.reset (new InternalReturn (_session));
|
_intreturn.reset (new InternalReturn (_session));
|
||||||
must_configure = true;
|
must_configure = true;
|
||||||
}
|
}
|
||||||
_intreturn->set_state (**niter, Stateful::current_state_version);
|
_intreturn->set_state (**niter, Stateful::current_state_version);
|
||||||
new_order.push_back (_intreturn);
|
|
||||||
} else if (is_monitor() && prop->value() == "monitor") {
|
} else if (is_monitor() && prop->value() == "monitor") {
|
||||||
if (!_monitor_control) {
|
if (!_monitor_control) {
|
||||||
_monitor_control.reset (new MonitorProcessor (_session));
|
_monitor_control.reset (new MonitorProcessor (_session));
|
||||||
must_configure = true;
|
must_configure = true;
|
||||||
}
|
}
|
||||||
_monitor_control->set_state (**niter, Stateful::current_state_version);
|
_monitor_control->set_state (**niter, Stateful::current_state_version);
|
||||||
new_order.push_back (_monitor_control);
|
|
||||||
} else {
|
} else {
|
||||||
ProcessorList::iterator o;
|
ProcessorList::iterator o;
|
||||||
|
|
||||||
|
|
@ -2412,7 +2388,11 @@ Route::set_processor_state (const XMLNode& node)
|
||||||
/* This processor could not be configured. Turn it into a UnknownProcessor */
|
/* This processor could not be configured. Turn it into a UnknownProcessor */
|
||||||
processor.reset (new UnknownProcessor (_session, **niter));
|
processor.reset (new UnknownProcessor (_session, **niter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* it doesn't matter if invisible processors are added here, as they
|
||||||
|
will be sorted out by setup_invisible_processors () shortly.
|
||||||
|
*/
|
||||||
|
|
||||||
new_order.push_back (processor);
|
new_order.push_back (processor);
|
||||||
must_configure = true;
|
must_configure = true;
|
||||||
}
|
}
|
||||||
|
|
@ -2516,78 +2496,58 @@ Route::release_return_buffer () const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a monitor send, if we don't already have one */
|
||||||
int
|
int
|
||||||
Route::listen_via (boost::shared_ptr<Route> route, Placement placement, bool /*active*/, bool aux)
|
Route::listen_via_monitor ()
|
||||||
{
|
{
|
||||||
vector<string> ports;
|
/* master never sends to control outs */
|
||||||
vector<string>::const_iterator i;
|
assert (!is_master ());
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set it up */
|
||||||
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
configure_processors (0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add an internal send to a route.
|
||||||
|
* @param route route to send to.
|
||||||
|
* @param placement placement for the send.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
Route::listen_via (boost::shared_ptr<Route> route, Placement placement)
|
||||||
|
{
|
||||||
|
assert (route != _session.monitor_out ());
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::ReaderLock rm (_processor_lock);
|
Glib::RWLock::ReaderLock rm (_processor_lock);
|
||||||
|
|
||||||
for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
|
for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
|
||||||
|
|
||||||
boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
|
boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend> (*x);
|
||||||
|
|
||||||
if (d && d->target_route() == route) {
|
if (d && d->target_route() == route) {
|
||||||
|
|
||||||
/* if the target is the control outs, then make sure
|
|
||||||
we take note of which i-send is doing that.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (route == _session.monitor_out()) {
|
|
||||||
_monitor_send = boost::dynamic_pointer_cast<Delivery>(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* already listening via the specified IO: do nothing */
|
/* already listening via the specified IO: do nothing */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<InternalSend> listener;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
boost::shared_ptr<InternalSend> listener (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux));
|
||||||
if (is_master()) {
|
add_processor (listener, placement);
|
||||||
|
|
||||||
if (route == _session.monitor_out()) {
|
|
||||||
/* master never sends to control outs */
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
listener.reset (new InternalSend (_session, _pannable, _mute_master, route, (aux ? Delivery::Aux : Delivery::Listen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (failed_constructor& err) {
|
} catch (failed_constructor& err) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route == _session.monitor_out()) {
|
|
||||||
_monitor_send = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2971,29 +2931,21 @@ Route::set_meter_point (MeterPoint p, bool force)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_meter_point = p;
|
||||||
|
|
||||||
bool meter_was_visible_to_user = _meter->display_to_user ();
|
bool meter_was_visible_to_user = _meter->display_to_user ();
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
|
|
||||||
if (p != MeterCustom) {
|
if (_meter_point != MeterCustom) {
|
||||||
// Move meter in the processors list to reflect the new position
|
|
||||||
ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
|
_meter->set_display_to_user (false);
|
||||||
_processors.erase(loc);
|
|
||||||
switch (p) {
|
|
||||||
case MeterInput:
|
|
||||||
loc = _processors.begin();
|
|
||||||
break;
|
|
||||||
case MeterPreFader:
|
|
||||||
loc = find (_processors.begin(), _processors.end(), _amp);
|
|
||||||
break;
|
|
||||||
case MeterPostFader:
|
|
||||||
loc = _processors.end();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
setup_invisible_processors ();
|
||||||
|
|
||||||
|
ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
|
||||||
|
|
||||||
ChanCount m_in;
|
ChanCount m_in;
|
||||||
|
|
||||||
if (loc == _processors.begin()) {
|
if (loc == _processors.begin()) {
|
||||||
|
|
@ -3006,16 +2958,12 @@ Route::set_meter_point (MeterPoint p, bool force)
|
||||||
|
|
||||||
_meter->reflect_inputs (m_in);
|
_meter->reflect_inputs (m_in);
|
||||||
|
|
||||||
_processors.insert (loc, _meter);
|
|
||||||
|
|
||||||
/* we do not need to reconfigure the processors, because the meter
|
/* we do not need to reconfigure the processors, because the meter
|
||||||
(a) is always ready to handle processor_max_streams
|
(a) is always ready to handle processor_max_streams
|
||||||
(b) is always an N-in/N-out processor, and thus moving
|
(b) is always an N-in/N-out processor, and thus moving
|
||||||
it doesn't require any changes to the other processors.
|
it doesn't require any changes to the other processors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_meter->set_display_to_user (false);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// just make it visible and let the user move it
|
// just make it visible and let the user move it
|
||||||
|
|
@ -3024,7 +2972,6 @@ Route::set_meter_point (MeterPoint p, bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_meter_point = p;
|
|
||||||
meter_change (); /* EMIT SIGNAL */
|
meter_change (); /* EMIT SIGNAL */
|
||||||
|
|
||||||
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
|
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
|
||||||
|
|
@ -3033,37 +2980,17 @@ Route::set_meter_point (MeterPoint p, bool force)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Route::put_monitor_send_at (Placement p)
|
Route::listen_position_changed ()
|
||||||
{
|
{
|
||||||
if (!_monitor_send) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||||
ProcessorList as_it_was (_processors);
|
ProcessorState pstate (this);
|
||||||
ProcessorList::iterator loc = find(_processors.begin(), _processors.end(), _monitor_send);
|
|
||||||
_processors.erase(loc);
|
|
||||||
|
|
||||||
switch (p) {
|
|
||||||
case PreFader:
|
|
||||||
loc = find(_processors.begin(), _processors.end(), _amp);
|
|
||||||
if (loc != _processors.begin()) {
|
|
||||||
--loc;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PostFader:
|
|
||||||
loc = _processors.end();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_processors.insert (loc, _monitor_send);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
|
|
||||||
if (configure_processors_unlocked (0)) {
|
if (configure_processors_unlocked (0)) {
|
||||||
_processors = as_it_was;
|
pstate.restore ();
|
||||||
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
configure_processors_unlocked (0); // it worked before we tried to add it ...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3077,16 +3004,19 @@ Route::put_monitor_send_at (Placement p)
|
||||||
boost::shared_ptr<CapturingProcessor>
|
boost::shared_ptr<CapturingProcessor>
|
||||||
Route::add_export_point()
|
Route::add_export_point()
|
||||||
{
|
{
|
||||||
// Check if it exists already
|
if (!_capturing_processor) {
|
||||||
boost::shared_ptr<CapturingProcessor> processor;
|
|
||||||
if ((processor = boost::dynamic_pointer_cast<CapturingProcessor> (*_processors.begin()))) {
|
_capturing_processor.reset (new CapturingProcessor (_session));
|
||||||
return processor;
|
_capturing_processor->activate ();
|
||||||
}
|
|
||||||
|
|
||||||
// ...else add it
|
{
|
||||||
processor.reset (new CapturingProcessor (_session));
|
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
|
||||||
add_processor (processor, _processors.begin());
|
configure_processors (0);
|
||||||
return processor;
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return _capturing_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
framecnt_t
|
framecnt_t
|
||||||
|
|
@ -3196,7 +3126,7 @@ double
|
||||||
Route::SoloControllable::get_value (void) const
|
Route::SoloControllable::get_value (void) const
|
||||||
{
|
{
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
return route.listening() ? 1.0f : 0.0f;
|
return route.listening_via_monitor() ? 1.0f : 0.0f;
|
||||||
} else {
|
} else {
|
||||||
return route.self_soloed() ? 1.0f : 0.0f;
|
return route.self_soloed() ? 1.0f : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
@ -3699,3 +3629,125 @@ Route::update_port_latencies (const PortSet& operands, const PortSet& feeders, b
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Put the invisible processors in the right place in _processors.
|
||||||
|
* Must be called with a writer lock on _processor_lock held.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Route::setup_invisible_processors ()
|
||||||
|
{
|
||||||
|
#ifdef NDEBUG
|
||||||
|
Glib::RWLock::WriterLock lm (_processor_lock, Glib::TryLock);
|
||||||
|
assert (!lm.locked ());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* we'll build this new list here and then use it */
|
||||||
|
|
||||||
|
ProcessorList new_processors;
|
||||||
|
|
||||||
|
/* find visible processors */
|
||||||
|
|
||||||
|
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||||
|
if ((*i)->display_to_user ()) {
|
||||||
|
new_processors.push_back (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the amp */
|
||||||
|
|
||||||
|
ProcessorList::iterator amp = new_processors.begin ();
|
||||||
|
while (amp != new_processors.end() && boost::dynamic_pointer_cast<Amp> (*amp) == 0) {
|
||||||
|
++amp;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (amp != _processors.end ());
|
||||||
|
|
||||||
|
/* and the processor after the amp */
|
||||||
|
|
||||||
|
ProcessorList::iterator after_amp = amp;
|
||||||
|
++after_amp;
|
||||||
|
|
||||||
|
/* METER */
|
||||||
|
|
||||||
|
if (_meter) {
|
||||||
|
switch (_meter_point) {
|
||||||
|
case MeterInput:
|
||||||
|
assert (!_meter->display_to_user ());
|
||||||
|
new_processors.push_front (_meter);
|
||||||
|
break;
|
||||||
|
case MeterPreFader:
|
||||||
|
assert (!_meter->display_to_user ());
|
||||||
|
new_processors.insert (amp, _meter);
|
||||||
|
break;
|
||||||
|
case MeterPostFader:
|
||||||
|
assert (!_meter->display_to_user ());
|
||||||
|
new_processors.insert (after_amp, _meter);
|
||||||
|
break;
|
||||||
|
case MeterCustom:
|
||||||
|
/* the meter is visible, so we don't touch it here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* MAIN OUTS */
|
||||||
|
|
||||||
|
if (_main_outs) {
|
||||||
|
assert (!_main_outs->display_to_user ());
|
||||||
|
new_processors.push_back (_main_outs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MONITOR CONTROL */
|
||||||
|
|
||||||
|
if (_monitor_control && is_monitor ()) {
|
||||||
|
assert (!_monitor_control->display_to_user ());
|
||||||
|
new_processors.push_front (_monitor_control);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* INTERNAL RETURN */
|
||||||
|
|
||||||
|
/* doing this here means that any monitor control will come just after
|
||||||
|
the return.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_intreturn) {
|
||||||
|
assert (!_intreturn->display_to_user ());
|
||||||
|
new_processors.push_front (_intreturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXPORT PROCESSOR */
|
||||||
|
|
||||||
|
if (_capturing_processor) {
|
||||||
|
assert (!_capturing_processor->display_to_user ());
|
||||||
|
new_processors.push_front (_capturing_processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
_processors = new_processors;
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: setup_invisible_processors\n", _name));
|
||||||
|
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||||
|
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -727,10 +727,8 @@ Session::hookup_io ()
|
||||||
/* relax */
|
/* relax */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
(*x)->listen_via (_monitor_out,
|
(*x)->listen_via_monitor ();
|
||||||
(Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
|
|
||||||
false, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2000,9 +1998,7 @@ Session::add_routes (RouteList& new_routes, bool save)
|
||||||
} else if ((*x)->is_master()) {
|
} else if ((*x)->is_master()) {
|
||||||
/* relax */
|
/* relax */
|
||||||
} else {
|
} else {
|
||||||
(*x)->listen_via (_monitor_out,
|
(*x)->listen_via_monitor ();
|
||||||
(Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
|
|
||||||
false, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2091,7 +2087,7 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*i)->listen_via (dest, p, true, true);
|
(*i)->listen_via (dest, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
graph_reordered ();
|
graph_reordered ();
|
||||||
|
|
@ -2207,7 +2203,7 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route->listening()) {
|
if (route->listening_via_monitor ()) {
|
||||||
|
|
||||||
if (Config->get_exclusive_solo()) {
|
if (Config->get_exclusive_solo()) {
|
||||||
/* new listen: disable all other listen */
|
/* new listen: disable all other listen */
|
||||||
|
|
@ -2363,7 +2359,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
|
||||||
something_soloed = true;
|
something_soloed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*i)->is_hidden() && (*i)->listening()) {
|
if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
|
||||||
if (Config->get_solo_control_is_listen_control()) {
|
if (Config->get_solo_control_is_listen_control()) {
|
||||||
listeners++;
|
listeners++;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3892,22 +3888,10 @@ Session::update_have_rec_enabled_track ()
|
||||||
void
|
void
|
||||||
Session::listen_position_changed ()
|
Session::listen_position_changed ()
|
||||||
{
|
{
|
||||||
Placement p;
|
|
||||||
|
|
||||||
switch (Config->get_listen_position()) {
|
|
||||||
case AfterFaderListen:
|
|
||||||
p = PostFader;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PreFaderListen:
|
|
||||||
p = PreFader;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||||
|
|
||||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||||
(*i)->put_monitor_send_at (p);
|
(*i)->listen_position_changed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3476,7 +3476,7 @@ Session::config_changed (std::string p, bool ours)
|
||||||
}
|
}
|
||||||
} else if (p == "solo-mute-override") {
|
} else if (p == "solo-mute-override") {
|
||||||
// catch_up_on_solo_mute_override ();
|
// catch_up_on_solo_mute_override ();
|
||||||
} else if (p == "listen-position") {
|
} else if (p == "listen-position" || p == "pfl-position") {
|
||||||
listen_position_changed ();
|
listen_position_changed ();
|
||||||
} else if (p == "solo-control-is-listen-control") {
|
} else if (p == "solo-control-is-listen-control") {
|
||||||
solo_control_mode_changed ();
|
solo_control_mode_changed ();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue