separate solo & listen. some minor fixes and additional related fixes still to come
git-svn-id: svn://localhost/ardour2/branches/3.0@5298 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
4df4574be4
commit
0d6515a243
@ -1459,32 +1459,34 @@ MixerStrip::set_button_names ()
|
||||
case Wide:
|
||||
rec_enable_button_label.set_text (_("Rec"));
|
||||
mute_button_label.set_text (_("Mute"));
|
||||
switch (Config->get_solo_model()) {
|
||||
case SoloInPlace:
|
||||
if (!Config->get_solo_control_is_listen_control()) {
|
||||
solo_button_label.set_text (_("Solo"));
|
||||
break;
|
||||
case SoloAFL:
|
||||
solo_button_label.set_text (_("AFL"));
|
||||
break;
|
||||
case SoloPFL:
|
||||
solo_button_label.set_text (_("PFL"));
|
||||
break;
|
||||
} else {
|
||||
switch (Config->get_listen_position()) {
|
||||
case AfterFaderListen:
|
||||
solo_button_label.set_text (_("AFL"));
|
||||
break;
|
||||
case PreFaderListen:
|
||||
solo_button_label.set_text (_("PFL"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
rec_enable_button_label.set_text (_("R"));
|
||||
mute_button_label.set_text (_("M"));
|
||||
switch (Config->get_solo_model()) {
|
||||
case SoloInPlace:
|
||||
if (!Config->get_solo_control_is_listen_control()) {
|
||||
solo_button_label.set_text (_("S"));
|
||||
break;
|
||||
case SoloAFL:
|
||||
solo_button_label.set_text (_("A"));
|
||||
break;
|
||||
case SoloPFL:
|
||||
solo_button_label.set_text (_("P"));
|
||||
break;
|
||||
} else {
|
||||
switch (Config->get_listen_position()) {
|
||||
case AfterFaderListen:
|
||||
solo_button_label.set_text (_("A"));
|
||||
break;
|
||||
case PreFaderListen:
|
||||
solo_button_label.set_text (_("P"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1063,6 +1063,10 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist)
|
||||
/* do not copy-n-paste amp */
|
||||
continue;
|
||||
|
||||
} else if (type->value() == "intsend" || type->value() == "intreturn") {
|
||||
/* do not copy-n-paste internal sends&returns */
|
||||
continue;
|
||||
|
||||
} else if (type->value() == "listen") {
|
||||
p.reset (new Delivery (_session, _route->mute_master(), **niter));
|
||||
|
||||
|
@ -1158,18 +1158,26 @@ RCOptionEditor::RCOptionEditor ()
|
||||
|
||||
add_option (_("Audio"), new OptionEditorHeading (_("Solo")));
|
||||
|
||||
ComboOption<SoloModel>* sm = new ComboOption<SoloModel> (
|
||||
"solo-model",
|
||||
_("Solo button controls"),
|
||||
mem_fun (*_rc_config, &RCConfiguration::get_solo_model),
|
||||
mem_fun (*_rc_config, &RCConfiguration::set_solo_model)
|
||||
|
||||
add_option (_("Audio"),
|
||||
new BoolOption (
|
||||
"solo-control-is-listen-control",
|
||||
_("Solo controls are Listen controls"),
|
||||
mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
|
||||
mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
|
||||
));
|
||||
|
||||
ComboOption<ListenPosition>* lp = new ComboOption<ListenPosition> (
|
||||
"listen-position",
|
||||
_("Listen Position"),
|
||||
mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
|
||||
mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
|
||||
);
|
||||
|
||||
sm->add (SoloInPlace, _("solo in place"));
|
||||
sm->add (SoloAFL, _("post-fader listen via monitor bus"));
|
||||
sm->add (SoloPFL, _("pre-fader listen via monitor bus"));
|
||||
lp->add (AfterFaderListen, _("after-fader listen"));
|
||||
lp->add (PreFaderListen, _("pre-fader listen"));
|
||||
|
||||
add_option (_("Audio"), sm);
|
||||
add_option (_("Audio"), lp);
|
||||
add_option (_("Audio"), new SoloMuteOptions (_rc_config));
|
||||
|
||||
add_option (_("Audio"),
|
||||
|
@ -2396,7 +2396,13 @@ void
|
||||
RouteTimeAxisView::set_button_names ()
|
||||
{
|
||||
rec_enable_button_label.set_text (_("r"));
|
||||
solo_button_label.set_text (_("s"));
|
||||
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
solo_button_label.set_text (_("l"));
|
||||
} else {
|
||||
solo_button_label.set_text (_("s"));
|
||||
}
|
||||
|
||||
mute_button_label.set_text (_("m"));
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
|
||||
connections.push_back (_route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed)));
|
||||
connections.push_back (_route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)));
|
||||
connections.push_back (_route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed)));
|
||||
connections.push_back (_route->listen_changed.connect (mem_fun(*this, &RouteUI::listen_changed)));
|
||||
connections.push_back (_route->solo_isolated_changed.connect (mem_fun(*this, &RouteUI::solo_changed)));
|
||||
|
||||
if (is_track()) {
|
||||
@ -322,102 +323,110 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
|
||||
return true;
|
||||
}
|
||||
multiple_solo_change = false;
|
||||
if (!ignore_toggle) {
|
||||
|
||||
if (Keyboard::is_context_menu_event (ev)) {
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
|
||||
if (solo_menu == 0) {
|
||||
build_solo_menu ();
|
||||
}
|
||||
_route->set_listen (!_route->listening(), this);
|
||||
|
||||
solo_menu->popup (1, ev->time);
|
||||
} else {
|
||||
|
||||
} else {
|
||||
|
||||
if (Keyboard::is_button2_event (ev)) {
|
||||
|
||||
// Primary-button2 click is the midi binding click
|
||||
// button2-click is "momentary"
|
||||
multiple_solo_change = false;
|
||||
if (!ignore_toggle) {
|
||||
|
||||
if (Keyboard::is_context_menu_event (ev)) {
|
||||
|
||||
if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
|
||||
wait_for_release = true;
|
||||
} else {
|
||||
return false;
|
||||
if (solo_menu == 0) {
|
||||
build_solo_menu ();
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
||||
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
||||
|
||||
/* Primary-Tertiary-click applies change to all routes */
|
||||
bool was_not_latched = false;
|
||||
if (!Config->get_solo_latched ()) {
|
||||
was_not_latched = true;
|
||||
/*
|
||||
XXX it makes no sense to solo all tracks if we're
|
||||
not in latched mode, but doing nothing feels like a bug,
|
||||
so do it anyway
|
||||
*/
|
||||
Config->set_solo_latched (true);
|
||||
}
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
|
||||
_session.set_all_solo (!_route->soloed());
|
||||
cmd->mark();
|
||||
_session.add_command (cmd);
|
||||
_session.commit_reversible_command ();
|
||||
multiple_solo_change = true;
|
||||
if (was_not_latched) {
|
||||
Config->set_solo_latched (false);
|
||||
}
|
||||
|
||||
solo_menu->popup (1, ev->time);
|
||||
|
||||
} else {
|
||||
|
||||
if (Keyboard::is_button2_event (ev)) {
|
||||
|
||||
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
||||
|
||||
// Primary-Secondary-click: exclusively solo this track, not a toggle */
|
||||
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this);
|
||||
_session.set_all_solo (false);
|
||||
_route->set_solo (true, this);
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
|
||||
|
||||
// shift-click: set this route to solo safe
|
||||
|
||||
if (Profile->get_sae() && ev->button == 1) {
|
||||
// button 1 and shift-click: disables solo_latched for this click
|
||||
// Primary-button2 click is the midi binding click
|
||||
// button2-click is "momentary"
|
||||
|
||||
if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
|
||||
wait_for_release = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
||||
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
||||
|
||||
/* Primary-Tertiary-click applies change to all routes */
|
||||
bool was_not_latched = false;
|
||||
if (!Config->get_solo_latched ()) {
|
||||
was_not_latched = true;
|
||||
/*
|
||||
XXX it makes no sense to solo all tracks if we're
|
||||
not in latched mode, but doing nothing feels like a bug,
|
||||
so do it anyway
|
||||
*/
|
||||
Config->set_solo_latched (true);
|
||||
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
|
||||
}
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
|
||||
_session.set_all_solo (!_route->soloed());
|
||||
cmd->mark();
|
||||
_session.add_command (cmd);
|
||||
_session.commit_reversible_command ();
|
||||
multiple_solo_change = true;
|
||||
if (was_not_latched) {
|
||||
Config->set_solo_latched (false);
|
||||
}
|
||||
|
||||
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
||||
|
||||
// Primary-Secondary-click: exclusively solo this track, not a toggle */
|
||||
|
||||
_session.begin_reversible_command (_("solo change"));
|
||||
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this);
|
||||
_session.set_all_solo (false);
|
||||
_route->set_solo (true, this);
|
||||
cmd->mark();
|
||||
_session.add_command(cmd);
|
||||
_session.commit_reversible_command ();
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
|
||||
|
||||
// shift-click: set this route to solo safe
|
||||
|
||||
if (Profile->get_sae() && ev->button == 1) {
|
||||
// button 1 and shift-click: disables solo_latched for this click
|
||||
if (!Config->get_solo_latched ()) {
|
||||
Config->set_solo_latched (true);
|
||||
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
|
||||
Config->set_solo_latched (false);
|
||||
}
|
||||
} else {
|
||||
_route->set_solo_isolated (!_route->solo_isolated(), this);
|
||||
wait_for_release = false;
|
||||
}
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
|
||||
/* Primary-button1: solo mix group.
|
||||
NOTE: Primary-button2 is MIDI learn.
|
||||
*/
|
||||
|
||||
if (ev->button == 1) {
|
||||
set_route_group_solo (_route, !_route->soloed());
|
||||
}
|
||||
|
||||
} else {
|
||||
_route->set_solo_isolated (!_route->solo_isolated(), this);
|
||||
wait_for_release = false;
|
||||
}
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
|
||||
/* Primary-button1: solo mix group.
|
||||
NOTE: Primary-button2 is MIDI learn.
|
||||
*/
|
||||
|
||||
if (ev->button == 1) {
|
||||
set_route_group_solo (_route, !_route->soloed());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* click: solo this route */
|
||||
if (wait_for_release) {
|
||||
_route->set_solo (!_route->soloed(), this);
|
||||
} else {
|
||||
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
|
||||
/* click: solo this route */
|
||||
if (wait_for_release) {
|
||||
_route->set_solo (!_route->soloed(), this);
|
||||
} else {
|
||||
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -614,7 +623,13 @@ RouteUI::send_blink (bool onoff)
|
||||
void
|
||||
RouteUI::solo_changed(void* src)
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_solo_display));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RouteUI::listen_changed(void* src)
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_solo_display));
|
||||
}
|
||||
|
||||
@ -622,21 +637,30 @@ void
|
||||
RouteUI::update_solo_display ()
|
||||
{
|
||||
bool x;
|
||||
vector<Gdk::Color> fg_colors;
|
||||
Gdk::Color c;
|
||||
|
||||
if (solo_button->get_active() != (x = _route->soloed())){
|
||||
ignore_toggle = true;
|
||||
solo_button->set_active(x);
|
||||
ignore_toggle = false;
|
||||
}
|
||||
|
||||
if (_route->solo_isolated()) {
|
||||
solo_button->set_visual_state (2);
|
||||
} else if (_route->soloed()) {
|
||||
solo_button->set_visual_state (1);
|
||||
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
|
||||
if (solo_button->get_active() != (x = _route->listening())) {
|
||||
ignore_toggle = true;
|
||||
solo_button->set_active(x);
|
||||
ignore_toggle = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
solo_button->set_visual_state (0);
|
||||
|
||||
if (solo_button->get_active() != (x = _route->soloed())){
|
||||
ignore_toggle = true;
|
||||
solo_button->set_active(x);
|
||||
ignore_toggle = false;
|
||||
}
|
||||
|
||||
if (_route->solo_isolated()) {
|
||||
solo_button->set_visual_state (2);
|
||||
} else if (_route->soloed()) {
|
||||
solo_button->set_visual_state (1);
|
||||
} else {
|
||||
solo_button->set_visual_state (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1383,7 +1407,9 @@ RouteUI::parameter_changed (string const & p)
|
||||
|
||||
if (p == "disable-disarm-during-roll") {
|
||||
check_rec_enable_sensitivity ();
|
||||
} else if (p == "solo-model") {
|
||||
} else if (p == "solo-control-is-listen-control") {
|
||||
set_button_names ();
|
||||
} else if (p == "listen-position") {
|
||||
set_button_names ();
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ class RouteUI : public virtual AxisView
|
||||
void solo_changed(void*);
|
||||
void solo_changed_so_update_mute ();
|
||||
void mute_changed(void*);
|
||||
void listen_changed(void*);
|
||||
virtual void processors_changed () {}
|
||||
void route_rec_enable_changed();
|
||||
void session_rec_enable_changed();
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
void attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset = 0);
|
||||
|
||||
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity);
|
||||
void ensure_buffers(const ChanCount& chns, size_t buffer_capacity);
|
||||
|
||||
const ChanCount& available() const { return _available; }
|
||||
ChanCount& available() { return _available; }
|
||||
|
@ -34,7 +34,7 @@ class InternalReturn : public Return
|
||||
InternalReturn (Session&);
|
||||
InternalReturn (Session&, const XMLNode&);
|
||||
|
||||
bool visible() const { return false; }
|
||||
bool visible() const { return true; }
|
||||
|
||||
XMLNode& state(bool full);
|
||||
XMLNode& get_state(void);
|
||||
|
@ -77,7 +77,9 @@ CONFIG_VARIABLE (bool, mute_affects_post_fader, "mute-affects-post-fader", true)
|
||||
CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", true)
|
||||
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
|
||||
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
|
||||
CONFIG_VARIABLE (SoloModel, solo_model, "solo-model", SoloInPlace)
|
||||
CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
|
||||
|
||||
CONFIG_VARIABLE (bool, solo_control_is_listen_control, "solo-control-is-listen-control", false)
|
||||
CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true)
|
||||
CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false)
|
||||
CONFIG_VARIABLE (bool, all_safe, "all-safe", false)
|
||||
|
@ -124,6 +124,7 @@ class Route : public SessionObject, public AutomatableControls
|
||||
void set_mute (bool yn, void* src);
|
||||
bool muted () const;
|
||||
|
||||
|
||||
/* controls use set_solo() to modify this route's solo state
|
||||
*/
|
||||
|
||||
@ -132,6 +133,9 @@ class Route : public SessionObject, public AutomatableControls
|
||||
|
||||
void set_solo_isolated (bool yn, void *src);
|
||||
bool solo_isolated() const;
|
||||
|
||||
void set_listen (bool yn, void* src);
|
||||
bool listening () const;
|
||||
|
||||
void set_phase_invert (bool yn);
|
||||
bool phase_invert() const;
|
||||
@ -229,6 +233,7 @@ class Route : public SessionObject, public AutomatableControls
|
||||
sigc::signal<void> active_changed;
|
||||
sigc::signal<void> phase_invert_changed;
|
||||
sigc::signal<void> denormal_protection_changed;
|
||||
sigc::signal<void,void*> listen_changed;
|
||||
sigc::signal<void,void*> solo_changed;
|
||||
sigc::signal<void,void*> solo_safe_changed;
|
||||
sigc::signal<void,void*> solo_isolated_changed;
|
||||
@ -262,7 +267,7 @@ class Route : public SessionObject, public AutomatableControls
|
||||
|
||||
sigc::signal<void,void*> SelectedChanged;
|
||||
|
||||
int listen_via (boost::shared_ptr<Route>, const std::string& name);
|
||||
int listen_via (boost::shared_ptr<Route>, bool);
|
||||
void drop_listen (boost::shared_ptr<Route>);
|
||||
|
||||
bool feeds (boost::shared_ptr<Route>);
|
||||
|
@ -723,9 +723,11 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
||||
/* session-wide solo/mute/rec-enable */
|
||||
|
||||
bool soloing() const { return _non_soloed_outs_muted; }
|
||||
|
||||
bool listening() const { return _listen_cnt > 0; }
|
||||
|
||||
void set_all_solo (bool);
|
||||
void set_all_mute (bool);
|
||||
void set_all_listen (bool);
|
||||
|
||||
sigc::signal<void,bool> SoloActive;
|
||||
sigc::signal<void> SoloChanged;
|
||||
@ -1031,6 +1033,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
||||
float _meter_hold;
|
||||
float _meter_falloff;
|
||||
bool _non_soloed_outs_muted;
|
||||
uint32_t _listen_cnt;
|
||||
|
||||
void set_worst_io_latencies ();
|
||||
void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
|
||||
@ -1451,16 +1454,15 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
||||
|
||||
/* mixer stuff */
|
||||
|
||||
bool solo_update_disabled;
|
||||
bool solo_update_disabled;
|
||||
|
||||
void route_listen_changed (void *src, boost::weak_ptr<Route>);
|
||||
void route_mute_changed (void *src);
|
||||
void route_solo_changed (void *src, boost::weak_ptr<Route>);
|
||||
void catch_up_on_solo ();
|
||||
void catch_up_on_solo_mute_override ();
|
||||
void solo_model_changed ();
|
||||
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
|
||||
void modify_solo_mute (bool, bool);
|
||||
void strip_portname_for_solo (std::string& portname);
|
||||
|
||||
void listen_position_changed ();
|
||||
void solo_control_mode_changed ();
|
||||
|
||||
/* REGION MANAGEMENT */
|
||||
|
||||
|
@ -330,10 +330,9 @@ namespace ARDOUR {
|
||||
AddHigher
|
||||
};
|
||||
|
||||
enum SoloModel {
|
||||
SoloInPlace,
|
||||
SoloAFL,
|
||||
SoloPFL
|
||||
enum ListenPosition {
|
||||
AfterFaderListen,
|
||||
PreFaderListen
|
||||
};
|
||||
|
||||
enum AutoConnectOption {
|
||||
@ -455,7 +454,7 @@ 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::MonitorModel& sf);
|
||||
std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf);
|
||||
std::istream& operator>>(std::istream& o, ARDOUR::SoloModel& 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::CrossfadeModel& sf);
|
||||
std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf);
|
||||
|
@ -130,6 +130,7 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
|
||||
}
|
||||
|
||||
_available.set(type, num_buffers);
|
||||
_count.set (type, num_buffers);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SLV2
|
||||
@ -149,6 +150,76 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
|
||||
assert(bufs[0]->capacity() >= buffer_capacity);
|
||||
}
|
||||
|
||||
/** Ensure that the number of buffers of each type @a type matches @a chns
|
||||
* and each buffer is of size at least @a buffer_capacity
|
||||
*/
|
||||
void
|
||||
BufferSet::ensure_buffers(const ChanCount& chns, size_t buffer_capacity)
|
||||
{
|
||||
if (chns == ChanCount::ZERO) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're a mirror just make sure we're ok
|
||||
if (_is_mirror) {
|
||||
assert(_count >= chns);
|
||||
return;
|
||||
}
|
||||
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
|
||||
// The vector of buffers of this type
|
||||
BufferVec& bufs = _buffers[*t];
|
||||
|
||||
uint32_t nbufs = chns.get (*t);
|
||||
|
||||
if (nbufs == 0) {
|
||||
// Nuke it
|
||||
for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
|
||||
delete (*i);
|
||||
}
|
||||
bufs.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's not enough or they're too small, just nuke the whole thing and
|
||||
// rebuild it (so I'm lazy..)
|
||||
if (bufs.size() < nbufs
|
||||
|| (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
|
||||
|
||||
// Nuke it
|
||||
for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
|
||||
delete (*i);
|
||||
}
|
||||
bufs.clear();
|
||||
|
||||
// Rebuild it
|
||||
for (size_t i = 0; i < nbufs; ++i) {
|
||||
bufs.push_back(Buffer::create(*t, buffer_capacity));
|
||||
}
|
||||
|
||||
_available.set (*t, nbufs);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SLV2
|
||||
// Ensure enough low level MIDI format buffers are available for conversion
|
||||
// in both directions (input & output, out-of-place)
|
||||
if (*t == DataType::MIDI && _lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2 + 1) {
|
||||
while (_lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2) {
|
||||
_lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Post-conditions
|
||||
assert(bufs[0]->type() == *t);
|
||||
assert(bufs.size() == _available.get(*t));
|
||||
assert(bufs[0]->capacity() >= buffer_capacity);
|
||||
}
|
||||
|
||||
assert (available() == chns);
|
||||
}
|
||||
|
||||
/** Get the capacity (size) of the available buffers of the given type.
|
||||
*
|
||||
* All buffers of a certain type always have the same capacity.
|
||||
|
@ -64,7 +64,7 @@ setup_enum_writer ()
|
||||
DenormalModel _DenormalModel;
|
||||
CrossfadeModel _CrossfadeModel;
|
||||
LayerModel _LayerModel;
|
||||
SoloModel _SoloModel;
|
||||
ListenPosition _ListenPosition;
|
||||
SampleFormat _SampleFormat;
|
||||
CDMarkerFormat _CDMarkerFormat;
|
||||
HeaderFormat _HeaderFormat;
|
||||
@ -229,10 +229,9 @@ setup_enum_writer ()
|
||||
REGISTER_ENUM (AddHigher);
|
||||
REGISTER (_LayerModel);
|
||||
|
||||
REGISTER_ENUM (SoloInPlace);
|
||||
REGISTER_ENUM (SoloAFL);
|
||||
REGISTER_ENUM (SoloPFL);
|
||||
REGISTER (_SoloModel);
|
||||
REGISTER_ENUM (AfterFaderListen);
|
||||
REGISTER_ENUM (PreFaderListen);
|
||||
REGISTER (_ListenPosition);
|
||||
|
||||
REGISTER_ENUM (AutoConnectPhysical);
|
||||
REGISTER_ENUM (AutoConnectMaster);
|
||||
|
@ -604,7 +604,7 @@ std::istream& operator>>(std::istream& o, AutoConnectOption& var) { return int_t
|
||||
std::istream& operator>>(std::istream& o, MonitorModel& var) { return int_to_type<MonitorModel> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, RemoteModel& var) { return int_to_type<RemoteModel> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, EditMode& var) { return int_to_type<EditMode> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, SoloModel& var) { return int_to_type<SoloModel> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, ListenPosition& var) { return int_to_type<ListenPosition> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, LayerModel& var) { return int_to_type<LayerModel> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_type<CrossfadeModel> (o, var); }
|
||||
std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type<SlaveSource> (o, var); }
|
||||
|
@ -60,7 +60,7 @@ bool
|
||||
InternalReturn::configure_io (ChanCount in, ChanCount out)
|
||||
{
|
||||
IOProcessor::configure_io (in, out);
|
||||
allocate_buffers (_session.get_block_size());
|
||||
allocate_buffers (_session.engine().frames_per_cycle());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@ InternalReturn::set_block_size (nframes_t nframes)
|
||||
void
|
||||
InternalReturn::allocate_buffers (nframes_t nframes)
|
||||
{
|
||||
buffers.ensure_buffers (DataType::AUDIO, _configured_input.n_audio(), nframes);
|
||||
buffers.ensure_buffers (DataType::MIDI, _configured_input.n_midi(), nframes);
|
||||
buffers.ensure_buffers (_configured_input, nframes);
|
||||
buffers.set_count (_configured_input);
|
||||
}
|
||||
|
||||
BufferSet*
|
||||
|
@ -454,14 +454,26 @@ Route::passthru (sframes_t start_frame, sframes_t end_frame, nframes_t nframes,
|
||||
}
|
||||
|
||||
bufs.set_count (_input->n_ports());
|
||||
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
|
||||
BufferSet::iterator o = bufs.begin(*t);
|
||||
PortSet& ports (_input->ports());
|
||||
|
||||
for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
|
||||
o->read_from (i->get_buffer(nframes), nframes);
|
||||
if (is_control() && _session.listening()) {
|
||||
|
||||
/* control/monitor bus ignores input ports when something is
|
||||
feeding the listen "stream". data will "arrive" into the
|
||||
route from the intreturn processor element.
|
||||
*/
|
||||
|
||||
bufs.silence (nframes, 0);
|
||||
|
||||
} else {
|
||||
|
||||
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
|
||||
|
||||
BufferSet::iterator o = bufs.begin(*t);
|
||||
PortSet& ports (_input->ports());
|
||||
|
||||
for (PortSet::iterator i = ports.begin(*t); i != ports.end(*t); ++i, ++o) {
|
||||
o->read_from (i->get_buffer(nframes), nframes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,6 +486,32 @@ Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t n
|
||||
process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, true, declick);
|
||||
}
|
||||
|
||||
void
|
||||
Route::set_listen (bool yn, void* src)
|
||||
{
|
||||
if (_control_outs) {
|
||||
if (yn != _control_outs->active()) {
|
||||
if (yn) {
|
||||
_control_outs->activate ();
|
||||
} else {
|
||||
_control_outs->deactivate ();
|
||||
}
|
||||
|
||||
listen_changed (src); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Route::listening () const
|
||||
{
|
||||
if (_control_outs) {
|
||||
return _control_outs->active ();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Route::set_solo (bool yn, void *src)
|
||||
{
|
||||
@ -506,33 +544,11 @@ Route::mod_solo_level (int32_t delta)
|
||||
_solo_level += delta;
|
||||
}
|
||||
|
||||
/* tell "special" delivery units what the solo situation is
|
||||
/* tell main outs what the solo situation is
|
||||
*/
|
||||
|
||||
switch (Config->get_solo_model()) {
|
||||
case SoloInPlace:
|
||||
/* main outs are used for soloing */
|
||||
_main_outs->set_solo_level (_solo_level);
|
||||
_main_outs->set_solo_isolated (_solo_isolated);
|
||||
if (_control_outs) {
|
||||
/* control outs just keep on playing */
|
||||
_control_outs->set_solo_level (0);
|
||||
_control_outs->set_solo_isolated (true);
|
||||
}
|
||||
break;
|
||||
|
||||
case SoloAFL:
|
||||
case SoloPFL:
|
||||
/* control outs are used for soloing */
|
||||
if (_control_outs) {
|
||||
_control_outs->set_solo_level (_solo_level);
|
||||
_control_outs->set_solo_isolated (_solo_isolated);
|
||||
}
|
||||
/* main outs just keep on playing */
|
||||
_main_outs->set_solo_level (0);
|
||||
_main_outs->set_solo_isolated (true);
|
||||
break;
|
||||
}
|
||||
_main_outs->set_solo_level (_solo_level);
|
||||
_main_outs->set_solo_isolated (_solo_isolated);
|
||||
}
|
||||
|
||||
void
|
||||
@ -546,28 +562,11 @@ Route::set_solo_isolated (bool yn, void *src)
|
||||
if (yn != _solo_isolated) {
|
||||
_solo_isolated = yn;
|
||||
|
||||
/* tell "special" delivery units what the solo situation is
|
||||
/* tell main outs what the solo situation is
|
||||
*/
|
||||
|
||||
switch (Config->get_solo_model()) {
|
||||
case SoloInPlace:
|
||||
_main_outs->set_solo_level (_solo_level);
|
||||
_main_outs->set_solo_isolated (_solo_isolated);
|
||||
if (_control_outs) {
|
||||
_main_outs->set_solo_level (1);
|
||||
_main_outs->set_solo_isolated (false);
|
||||
}
|
||||
break;
|
||||
case SoloAFL:
|
||||
case SoloPFL:
|
||||
if (_control_outs) {
|
||||
_control_outs->set_solo_level (_solo_level);
|
||||
_control_outs->set_solo_isolated (_solo_isolated);
|
||||
}
|
||||
_main_outs->set_solo_level (1);
|
||||
_main_outs->set_solo_isolated (false);
|
||||
break;
|
||||
}
|
||||
_main_outs->set_solo_level (_solo_level);
|
||||
_main_outs->set_solo_isolated (_solo_isolated);
|
||||
|
||||
solo_isolated_changed (src);
|
||||
}
|
||||
@ -711,7 +710,9 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
|
||||
}
|
||||
|
||||
// XXX: do we want to emit the signal here ? change call order.
|
||||
processor->activate ();
|
||||
if (!boost::dynamic_pointer_cast<InternalSend>(processor)) {
|
||||
processor->activate ();
|
||||
}
|
||||
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
|
||||
|
||||
_output->set_user_latency (0);
|
||||
@ -1862,7 +1863,8 @@ Route::get_return_buffer () const
|
||||
boost::shared_ptr<InternalReturn> d = boost::dynamic_pointer_cast<InternalReturn>(*x);
|
||||
|
||||
if (d) {
|
||||
return d->get_buffers ();
|
||||
BufferSet* bs = d->get_buffers ();
|
||||
return bs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1884,7 +1886,7 @@ Route::release_return_buffer () const
|
||||
}
|
||||
|
||||
int
|
||||
Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
|
||||
Route::listen_via (boost::shared_ptr<Route> route, bool active)
|
||||
{
|
||||
vector<string> ports;
|
||||
vector<string>::const_iterator i;
|
||||
@ -1893,6 +1895,7 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
|
||||
Glib::RWLock::ReaderLock rm (_processor_lock);
|
||||
|
||||
for (ProcessorList::iterator x = _processors.begin(); x != _processors.end(); ++x) {
|
||||
|
||||
boost::shared_ptr<InternalSend> d = boost::dynamic_pointer_cast<InternalSend>(*x);
|
||||
|
||||
if (d && d->target_route() == route) {
|
||||
@ -1921,6 +1924,10 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (route == _session.control_out()) {
|
||||
_control_outs = listener;
|
||||
}
|
||||
|
||||
add_processor (listener, PreFader);
|
||||
|
||||
return 0;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "ardour/analyser.h"
|
||||
#include "ardour/audio_buffer.h"
|
||||
#include "ardour/audio_diskstream.h"
|
||||
#include "ardour/audio_port.h"
|
||||
#include "ardour/audio_track.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/audiofilesource.h"
|
||||
@ -269,16 +270,6 @@ Session::Session (AudioEngine &eng,
|
||||
RouteList rl;
|
||||
int control_id = 1;
|
||||
|
||||
if (control_out_channels) {
|
||||
ChanCount count(DataType::AUDIO, control_out_channels);
|
||||
shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
|
||||
r->input()->ensure_io (count, false, this);
|
||||
r->output()->ensure_io (count, false, this);
|
||||
r->set_remote_control_id (control_id++);
|
||||
|
||||
rl.push_back (r);
|
||||
}
|
||||
|
||||
if (master_out_channels) {
|
||||
ChanCount count(DataType::AUDIO, master_out_channels);
|
||||
shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
|
||||
@ -292,6 +283,16 @@ Session::Session (AudioEngine &eng,
|
||||
output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
|
||||
}
|
||||
|
||||
if (control_out_channels) {
|
||||
ChanCount count(DataType::AUDIO, control_out_channels);
|
||||
shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
|
||||
r->input()->ensure_io (count, false, this);
|
||||
r->output()->ensure_io (count, false, this);
|
||||
r->set_remote_control_id (control_id++);
|
||||
|
||||
rl.push_back (r);
|
||||
}
|
||||
|
||||
if (!rl.empty()) {
|
||||
add_routes (rl, false);
|
||||
}
|
||||
@ -680,11 +681,46 @@ Session::when_engine_running ()
|
||||
|
||||
if (_control_out) {
|
||||
|
||||
uint32_t limit = _control_out->n_outputs().n_total();
|
||||
/* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
|
||||
are undefined, at best.
|
||||
*/
|
||||
|
||||
/* control out listens to master bus (but ignores it
|
||||
under some conditions)
|
||||
*/
|
||||
|
||||
uint32_t limit = _control_out->n_inputs().n_audio();
|
||||
|
||||
if (_master_out) {
|
||||
for (uint32_t n = 0; n < limit; ++n) {
|
||||
AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
|
||||
AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
|
||||
|
||||
if (o) {
|
||||
string connect_to = o->name();
|
||||
if (_control_out->input()->connect (p, connect_to, this)) {
|
||||
error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
|
||||
<< endmsg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* connect control out to physical outs, but use ones after the master
|
||||
if possible
|
||||
*/
|
||||
|
||||
/* XXX this logic is wrong for mixed port types */
|
||||
|
||||
uint32_t shift = _master_out->n_outputs().n_audio();
|
||||
uint32_t mod = _master_out->n_outputs().n_audio();
|
||||
limit = _control_out->n_outputs().n_audio();
|
||||
|
||||
for (uint32_t n = 0; n < limit; ++n) {
|
||||
|
||||
Port* p = _control_out->output()->nth (n);
|
||||
string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
|
||||
string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
|
||||
|
||||
if (!connect_to.empty()) {
|
||||
if (_control_out->output()->connect (p, connect_to, this)) {
|
||||
@ -764,7 +800,7 @@ Session::hookup_io ()
|
||||
continue;
|
||||
}
|
||||
|
||||
(*x)->listen_via (_control_out, X_("listen"));
|
||||
(*x)->listen_via (_control_out, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -780,9 +816,13 @@ Session::hookup_io ()
|
||||
|
||||
graph_reordered ();
|
||||
|
||||
/* update mixer solo state */
|
||||
/* update the full solo state, which can't be
|
||||
correctly determined on a per-route basis, but
|
||||
needs the global overview that only the session
|
||||
has.
|
||||
*/
|
||||
|
||||
catch_up_on_solo();
|
||||
update_route_solo_state ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -2069,6 +2109,7 @@ Session::add_routes (RouteList& new_routes, bool save)
|
||||
|
||||
boost::weak_ptr<Route> wpr (*x);
|
||||
|
||||
(*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
|
||||
(*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
|
||||
(*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
|
||||
(*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
|
||||
@ -2090,7 +2131,8 @@ Session::add_routes (RouteList& new_routes, bool save)
|
||||
if ((*x)->is_control() || (*x)->is_master()) {
|
||||
continue;
|
||||
}
|
||||
(*x)->listen_via (_control_out, "control");
|
||||
cerr << "Add listen via control outs\n";
|
||||
(*x)->listen_via (_control_out, false);
|
||||
}
|
||||
|
||||
resort_routes ();
|
||||
@ -2139,7 +2181,7 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, boost::shared_ptr<Ro
|
||||
continue;
|
||||
}
|
||||
|
||||
(*i)->listen_via (dest, "aux");
|
||||
(*i)->listen_via (dest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2253,6 +2295,22 @@ Session::route_mute_changed (void* src)
|
||||
set_dirty ();
|
||||
}
|
||||
|
||||
void
|
||||
Session::route_listen_changed (void* src, boost::weak_ptr<Route> wpr)
|
||||
{
|
||||
boost::shared_ptr<Route> route = wpr.lock();
|
||||
if (!route) {
|
||||
error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (route->listening()) {
|
||||
_listen_cnt++;
|
||||
} else if (_listen_cnt > 0) {
|
||||
_listen_cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
|
||||
{
|
||||
@ -2329,34 +2387,6 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::catch_up_on_solo ()
|
||||
{
|
||||
/* this is called after set_state() to catch the full solo
|
||||
state, which can't be correctly determined on a per-route
|
||||
basis, but needs the global overview that only the session
|
||||
has.
|
||||
*/
|
||||
update_route_solo_state();
|
||||
}
|
||||
|
||||
void
|
||||
Session::catch_up_on_solo_mute_override ()
|
||||
{
|
||||
if (Config->get_solo_model() != SoloInPlace) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is called whenever the param solo-mute-override is
|
||||
changed.
|
||||
*/
|
||||
shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
// (*i)->catch_up_on_solo_mute_override ();
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<Route>
|
||||
Session::route_by_name (string name)
|
||||
{
|
||||
@ -3491,6 +3521,20 @@ Session::set_all_solo (bool yn)
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_all_listen (bool yn)
|
||||
{
|
||||
shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
if (!(*i)->is_hidden()) {
|
||||
(*i)->set_listen (yn, this);
|
||||
}
|
||||
}
|
||||
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_all_mute (bool yn)
|
||||
{
|
||||
@ -4257,19 +4301,16 @@ Session::update_have_rec_enabled_diskstream ()
|
||||
}
|
||||
|
||||
void
|
||||
Session::solo_model_changed ()
|
||||
Session::listen_position_changed ()
|
||||
{
|
||||
Placement p;
|
||||
|
||||
switch (Config->get_solo_model()) {
|
||||
case SoloInPlace:
|
||||
return;
|
||||
|
||||
case SoloAFL:
|
||||
switch (Config->get_listen_position()) {
|
||||
case AfterFaderListen:
|
||||
p = PostFader;
|
||||
break;
|
||||
|
||||
case SoloPFL:
|
||||
case PreFaderListen:
|
||||
p = PreFader;
|
||||
break;
|
||||
}
|
||||
@ -4281,6 +4322,18 @@ Session::solo_model_changed ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::solo_control_mode_changed ()
|
||||
{
|
||||
/* cancel all solo or all listen when solo control mode changes */
|
||||
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
set_all_solo (false);
|
||||
} else {
|
||||
set_all_listen (false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::route_group_changed ()
|
||||
{
|
||||
|
@ -152,6 +152,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||
|
||||
|
||||
_non_soloed_outs_muted = false;
|
||||
_listen_cnt = 0;
|
||||
g_atomic_int_set (&processing_prohibited, 0);
|
||||
_transport_speed = 0;
|
||||
_last_transport_speed = 0;
|
||||
@ -3152,10 +3153,13 @@ Session::config_changed (std::string p, bool ours)
|
||||
}
|
||||
} else if (p == "solo-mute-override") {
|
||||
// catch_up_on_solo_mute_override ();
|
||||
} else if (p == "solo-model") {
|
||||
solo_model_changed ();
|
||||
} else if (p == "listen-position") {
|
||||
listen_position_changed ();
|
||||
} else if (p == "solo-control-is-listen-control") {
|
||||
solo_control_mode_changed ();
|
||||
}
|
||||
|
||||
|
||||
set_dirty ();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user