13
0

solo models work again (amazing how hard this was); remove crufty debug output; remove scrollbars on editor (and temporarily lose zoom controls)

git-svn-id: svn://localhost/ardour2/branches/3.0@5207 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-06-17 15:50:29 +00:00
parent 34930fc8cf
commit 1e8047f0ed
15 changed files with 182 additions and 119 deletions

View File

@ -407,7 +407,7 @@ Editor::Editor ()
tempo_label.set_no_show_all();
meter_label.set_name ("EditorTimeButton");
meter_label.set_size_request (-1, (int)timebar_height);
meter_label.set_alignment (1.0, 0.5);
meter_label.set_alignment (0.0, 0.5);
meter_label.set_padding (5,0);
meter_label.hide();
meter_label.set_no_show_all();
@ -487,11 +487,9 @@ Editor::Editor ()
ruler_label_event_box.add (ruler_label_vbox);
ruler_label_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
ruler_label_event_box.set_name ("TimebarLabelBase");
ruler_label_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release));
time_button_event_box.add (time_button_vbox);
time_button_event_box.set_name ("TimebarLabelBase");
time_button_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
time_button_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release));
@ -510,32 +508,15 @@ Editor::Editor ()
edit_packer.set_border_width (0);
edit_packer.set_name ("EditorWindow");
/* summary */
edit_packer.attach (*_summary, 0, 2, 0, 1, FILL|EXPAND, SHRINK, 0, 0);
edit_packer.attach (ruler_label_event_box, 1, 2, 0, 1, FILL, SHRINK, 0, 0);
edit_packer.attach (time_button_event_box, 1, 2, 1, 2, FILL, SHRINK, 0, 0);
/* labels for rulers (mins:secs, timecode, samples, bars:beats) */
edit_packer.attach (ruler_label_event_box, 0, 1, 1, 2, FILL, SHRINK, 0, 0);
edit_packer.attach (time_canvas_event_box, 2, 3, 0, 1, FILL|EXPAND, FILL, 0, 0);
/* labels for time lines (meter, tempo, markers) */
edit_packer.attach (time_button_event_box, 0, 1, 2, 3, FILL, SHRINK, 0, 0);
edit_packer.attach (controls_layout, 1, 2, 2, 3, FILL, FILL|EXPAND, 0, 0);
edit_packer.attach (track_canvas_event_box, 2, 3, 1, 3, FILL|EXPAND, FILL|EXPAND, 0, 0);
/* rulers */
edit_packer.attach (time_canvas_event_box, 1, 2, 1, 2, FILL|EXPAND, FILL, 0, 0);
/* LHS controls for tracks */
edit_packer.attach (controls_layout, 0, 1, 3, 4, FILL, FILL|EXPAND, 0, 0);
/* main canvas (which has the time line canvas items at the top of it) */
edit_packer.attach (track_canvas_event_box, 1, 2, 2, 4, FILL|EXPAND, FILL|EXPAND, 0, 0);
/* zoom controls */
edit_packer.attach (zoom_box, 0, 1, 4, 5, FILL, FILL, 0, 0);
/* h scroller */
edit_packer.attach (edit_hscrollbar, 1, 2, 4, 5, FILL|EXPAND, FILL, 0, 0);
/* v scroller */
edit_packer.attach (edit_vscrollbar, 3, 4, 3, 4, FILL, FILL|EXPAND, 0, 0);
edit_packer.attach (*_summary, 0, 3, 3, 4, FILL|EXPAND, SHRINK, 0, 0);
bottom_hbox.set_border_width (2);
bottom_hbox.set_spacing (3);
@ -3143,11 +3124,15 @@ Editor::setup_toolbar ()
zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus"));
zoom_box.pack_start (zoom_focus_selector, true, true);
zoom_box.pack_start (zoom_out_button, false, false);
zoom_box.pack_start (zoom_in_button, false, false);
zoom_box.pack_start (zoom_out_full_button, false, false);
HBox* zbc = manage (new HBox);
zbc->pack_start (zoom_focus_selector, false, false);
zoom_vbox.pack_start (*zbc, false, false);
zoom_vbox.pack_start (zoom_box, false, false);
snap_box.set_spacing (1);
snap_box.set_border_width (2);

View File

@ -1677,6 +1677,7 @@ public:
Glib::RefPtr<Gtk::RadioAction> zoom_focus_action (Editing::ZoomFocus);
Gtk::HBox zoom_box;
Gtk::VBox zoom_vbox;
void zoom_adjustment_changed();

View File

@ -1089,7 +1089,7 @@ RCOptionEditor::RCOptionEditor ()
mem_fun (*_rc_config, &RCConfiguration::set_solo_model)
);
sm->add (InverseMute, _("in place"));
sm->add (SoloInPlace, _("in place"));
sm->add (SoloBus, _("via bus"));
add_option (_("Audio"), sm);

View File

@ -64,12 +64,8 @@ public:
void no_outs_cuz_we_no_monitor(bool);
void mod_solo_level (int32_t);
uint32_t solo_level() const { return _solo_level; }
bool soloed () const { return (bool) _solo_level; }
bool solo_isolated() const { return _solo_isolated; }
void set_solo_isolated (bool);
void set_solo_level (int32_t sl) { _solo_level = sl; }
void set_solo_isolated (bool yn) { _solo_isolated = yn; }
void cycle_start (nframes_t);
void increment_output_offset (nframes_t);

View File

@ -77,7 +77,7 @@ 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", InverseMute)
CONFIG_VARIABLE (SoloModel, solo_model, "solo-model", SoloInPlace)
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)

View File

@ -124,8 +124,11 @@ 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
*/
void set_solo (bool yn, void *src);
bool soloed() const;
bool soloed () const { return (bool) _solo_level; }
void set_solo_isolated (bool yn, void *src);
bool solo_isolated() const;
@ -315,6 +318,7 @@ class Route : public SessionObject, public AutomatableControls
void catch_up_on_solo_mute_override ();
void mod_solo_level (int32_t);
uint32_t solo_level () const { return _solo_level; }
void set_block_size (nframes_t nframes);
bool has_external_redirects() const;
void curve_reallocate ();
@ -340,13 +344,16 @@ class Route : public SessionObject, public AutomatableControls
ProcessorList _processors;
mutable Glib::RWLock _processor_lock;
boost::shared_ptr<Delivery> _main_outs;
boost::shared_ptr<Delivery> _control_outs; // XXX to be removed/generalized by listen points
boost::shared_ptr<Delivery> _control_outs;
boost::shared_ptr<InternalReturn> _intreturn;
Flag _flags;
int _pending_declick;
MeterPoint _meter_point;
uint32_t _phase_invert;
uint32_t _solo_level;
bool _solo_isolated;
bool _denormal_protection;
bool _recordable : 1;

View File

@ -331,7 +331,7 @@ namespace ARDOUR {
};
enum SoloModel {
InverseMute,
SoloInPlace,
SoloBus
};

View File

@ -53,6 +53,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Mute
, _solo_level (0)
, _solo_isolated (false)
, _mute_master (mm)
{
_output_offset = 0;
_current_gain = 1.0;
@ -267,15 +268,9 @@ Delivery::set_state (const XMLNode& node)
if ((prop = node.property ("role")) != 0) {
_role = Role (string_2_enum (prop->value(), _role));
}
if ((prop = node.property ("solo_level")) != 0) {
_solo_level = 0; // needed for the reset to work
mod_solo_level (atoi (prop->value()));
}
if ((prop = node.property ("solo-isolated")) != 0) {
set_solo_isolated (prop->value() == "yes");
// std::cerr << this << ' ' << _name << " set role to " << enum_2_string (_role) << std::endl;
} else {
// std::cerr << this << ' ' << _name << " NO ROLE INFO\n";
}
XMLNode* pan_node = node.child (X_("Panner"));
@ -423,11 +418,15 @@ Delivery::target_gain ()
break;
}
if (_solo_level) {
desired_gain = 1.0;
} else {
if (_solo_isolated) {
if (_solo_isolated) {
/* ... but we are isolated from all that nonsense */
desired_gain = _mute_master->mute_gain_at (mp);
} else if (_session.soloing()) {
@ -442,26 +441,6 @@ Delivery::target_gain ()
return desired_gain;
}
void
Delivery::mod_solo_level (int32_t delta)
{
if (delta < 0) {
if (_solo_level >= (uint32_t) delta) {
_solo_level += delta;
} else {
_solo_level = 0;
}
} else {
_solo_level += delta;
}
}
void
Delivery::set_solo_isolated (bool yn)
{
_solo_isolated = yn;
}
void
Delivery::no_outs_cuz_we_no_monitor (bool yn)
{

View File

@ -228,7 +228,7 @@ setup_enum_writer ()
REGISTER_ENUM (AddHigher);
REGISTER (_LayerModel);
REGISTER_ENUM (InverseMute);
REGISTER_ENUM (SoloInPlace);
REGISTER_ENUM (SoloBus);
REGISTER (_SoloModel);

View File

@ -81,12 +81,38 @@ InternalSend::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame,
BufferSet& sendbufs = _session.get_mix_buffers (bufs.count());
sendbufs.read_from (bufs, nframes);
assert(sendbufs.count() == bufs.count());
/* gain control */
gain_t tgain = target_gain ();
if (tgain != _current_gain) {
/* target gain has changed */
Amp::apply_gain (sendbufs, nframes, _current_gain, tgain);
_current_gain = tgain;
} else if (tgain == 0.0) {
/* we were quiet last time, and we're still supposed to be quiet.
*/
_meter->reset ();
Amp::apply_simple_gain (sendbufs, nframes, 0.0);
return;
} else if (tgain != 1.0) {
/* target gain has not changed, but is not unity */
Amp::apply_simple_gain (sendbufs, nframes, tgain);
}
// Can't automate gain for sends or returns yet because we need different buffers
// so that we don't overwrite the main automation data for the route amp
// _amp->setup_gain_automation (start_frame, end_frame, nframes);
_amp->run (sendbufs, start_frame, end_frame, nframes);
/* consider metering */
@ -137,6 +163,8 @@ InternalSend::set_state (const XMLNode& node)
{
const XMLProperty* prop;
Send::set_state (node);
if ((prop = node.property ("target")) != 0) {
_send_to_id = prop->value();
@ -148,9 +176,7 @@ InternalSend::set_state (const XMLNode& node)
if (!IO::connecting_legal) {
connect_c = IO::ConnectingLegal.connect (mem_fun (*this, &InternalSend::connect_when_legal));
std::cerr << "connect later!\n";
} else {
std::cerr << "connect NOW!\n";
connect_when_legal ();
}
}
@ -161,8 +187,6 @@ InternalSend::set_state (const XMLNode& node)
int
InternalSend::connect_when_legal ()
{
std::cerr << "IOP/send connecting now that its legal\n";
connect_c.disconnect ();
if (_send_to_id == "0") {
@ -172,13 +196,12 @@ InternalSend::connect_when_legal ()
if ((_send_to = _session.route_by_id (_send_to_id)) == 0) {
error << X_("cannot find route to connect to") << endmsg;
std::cerr << "cannot find route with ID " << _send_to_id << std::endl;
} else {
std::cerr << "got target send as " << _send_to << std::endl;
}
return -1;
}
if ((target = _send_to->get_return_buffer ()) == 0) {
error << X_("target for internal send has no return buffer") << endmsg;
return -1;
}
return 0;

View File

@ -64,8 +64,6 @@ IOProcessor::IOProcessor (Session& s, bool with_input, bool with_output,
if (with_output) {
_output.reset (new IO(s, io_name.empty() ? proc_name : io_name, IO::Output, dtype));
}
cerr << "fresh create IOP name = " << proc_name << " in = " << _input << " out = " << _output << endl;
}
/* create an IOProcessor that proxies to an existing IO object */
@ -76,7 +74,6 @@ IOProcessor::IOProcessor (Session& s, boost::shared_ptr<IO> in, boost::shared_pt
, _input (in)
, _output (out)
{
cerr << "XML create IOP name = " << proc_name << " in = " << in << " out = " << out << endl;
if (in) {
_own_input = false;
} else {
@ -165,8 +162,6 @@ IOProcessor::set_state (const XMLNode& node)
_own_output = (prop->value() == "yes");
}
cerr << _name << " own input = " << _own_input << " output = " << _own_output << endl;
/* don't attempt to set state for a proxied IO that we don't own */
XMLNodeList nlist = node.children();

View File

@ -152,10 +152,7 @@ Processor::set_state (const XMLNode& node)
// may not exist for legacy 3.0 sessions
if ((prop = node.property ("id")) != 0) {
_id = prop->value();
cerr << "---------------- ID for processor " << name() << " = " << _id << endl;
} else {
cerr << "---------------- NO ID for processor " << name() << endl;
}
}
XMLNodeList nlist = node.children();
XMLNodeIterator niter;

View File

@ -37,6 +37,7 @@
#include "ardour/buffer_set.h"
#include "ardour/configuration.h"
#include "ardour/cycle_timer.h"
#include "ardour/delivery.h"
#include "ardour/dB.h"
#include "ardour/internal_send.h"
#include "ardour/internal_return.h"
@ -114,6 +115,8 @@ Route::Route (Session& sess, const XMLNode& node, DataType default_type)
void
Route::init ()
{
_solo_level = 0;
_solo_isolated = false;
_active = true;
processor_max_streams.reset();
_solo_safe = false;
@ -475,7 +478,7 @@ Route::passthru_silence (sframes_t start_frame, sframes_t end_frame, nframes_t n
void
Route::set_solo (bool yn, void *src)
{
if (_solo_safe) {
if (_solo_safe || _solo_isolated) {
return;
}
@ -484,17 +487,52 @@ Route::set_solo (bool yn, void *src)
return;
}
if (_main_outs->soloed() != yn) {
_main_outs->mod_solo_level (yn ? 1 : -1);
if (soloed() != yn) {
mod_solo_level (yn ? 1 : -1);
solo_changed (src); /* EMIT SIGNAL */
_solo_control->Changed (); /* EMIT SIGNAL */
}
}
bool
Route::soloed() const
void
Route::mod_solo_level (int32_t delta)
{
return _main_outs->soloed ();
if (delta < 0) {
if (_solo_level >= (uint32_t) delta) {
_solo_level += delta;
} else {
_solo_level = 0;
}
} else {
_solo_level += delta;
}
/* tell "special" delivery units 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 SoloBus:
/* 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;
}
}
void
@ -505,14 +543,39 @@ Route::set_solo_isolated (bool yn, void *src)
return;
}
_main_outs->set_solo_isolated (yn);
solo_isolated_changed (src);
if (yn != _solo_isolated) {
_solo_isolated = yn;
/* tell "special" delivery units 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 SoloBus:
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;
}
solo_isolated_changed (src);
}
}
bool
Route::solo_isolated () const
{
return _main_outs->solo_isolated();
return _solo_isolated;
}
void
@ -535,6 +598,7 @@ Route::muted() const
return _mute_master->muted ();
}
#if 0
static void
dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
{
@ -545,6 +609,7 @@ dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& p
}
cerr << "}" << endl;
}
#endif
int
Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
@ -567,7 +632,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, Placement placemen
ProcessorList::iterator p;
p = _processors.end();
--p;
cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
@ -621,8 +685,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
loc = iter;
}
cerr << "Adding " << processor->name() << " @ " << processor << endl;
_processors.insert (loc, processor);
// Set up processor list channels. This will set processor->[input|output]_streams(),
@ -705,9 +767,6 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
try {
if ((prop = node.property ("type")) != 0) {
cerr << _name << " : got processor type " << prop->value() << endl;
boost::shared_ptr<Processor> processor;
if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
@ -757,7 +816,7 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
} else if (prop->value() == "intsend") {
processor.reset (new InternalSend (_session, _mute_master, node));
} else if (prop->value() == "intreturn") {
if (_intreturn) {
@ -792,7 +851,6 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter
ProcessorList::iterator p;
p = _processors.end();
--p;
cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
@ -1213,10 +1271,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
list< pair<ChanCount,ChanCount> > configuration;
uint32_t index = 0;
cerr << "Processor check with " << _processors.size() << endl;
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
cerr << "Checking out " << (*p)->name() << " type = " << endl;
if ((*p)->can_support_io_configuration(in, out)) {
configuration.push_back(make_pair(in, out));
in = out;
@ -1538,6 +1593,15 @@ Route::_set_state (const XMLNode& node, bool call_base)
set_processor_state (processor_state);
if ((prop = node.property ("solo_level")) != 0) {
_solo_level = 0; // needed for mod_solo_level() to work
mod_solo_level (atoi (prop->value()));
}
if ((prop = node.property ("solo-isolated")) != 0) {
set_solo_isolated (prop->value() == "yes", this);
}
if ((prop = node.property (X_("phase-invert"))) != 0) {
set_phase_invert (prop->value()=="yes"?true:false);
}
@ -1667,8 +1731,6 @@ Route::set_processor_state (const XMLNode& node)
XMLNodeConstIterator niter;
ProcessorList::iterator i, o;
dump_processors ("set processor states", _processors);
// Iterate through existing processors, remove those which are not in the state list
for (i = _processors.begin(); i != _processors.end(); ) {
@ -1841,11 +1903,21 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
{
Glib::RWLock::ReaderLock rm (_processor_lock);
for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) {
boost::shared_ptr<const InternalSend> d = boost::dynamic_pointer_cast<const InternalSend>(*x);
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) {
/* if the target is the control outs, then make sure
we take note of which i-send is doing that.
*/
if (route == _session.control_out()) {
_control_outs = boost::dynamic_pointer_cast<Delivery>(d);
}
/* already listening via the specified IO: do nothing */
return 0;
}
}
@ -1894,6 +1966,10 @@ Route::drop_listen (boost::shared_ptr<Route> route)
}
rl.release ();
if (route == _session.control_out()) {
_control_outs.reset ();
}
}
void

View File

@ -112,7 +112,7 @@ Send::get_state(void)
XMLNode&
Send::state(bool full)
{
XMLNode& node = IOProcessor::state(full);
XMLNode& node = Delivery::state(full);
char buf[32];
node.add_property ("type", "send");

View File

@ -790,7 +790,6 @@ Session::hookup_io ()
_state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
/* now handle the whole enchilada as if it was one
graph reorder event.
*/
@ -2247,15 +2246,20 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
if ((*i)->feeds (route)) {
/* do it */
(*i)->main_outs()->mod_solo_level (delta);
(*i)->mod_solo_level (delta);
}
}
/* make sure master is never muted by solo */
if (_master_out->main_outs()->solo_level() == 0) {
_master_out->main_outs()->mod_solo_level (1);
if (_master_out->solo_level() == 0) {
_master_out->mod_solo_level (1);
}
/* ditto for control outs make sure master is never muted by solo */
if (_control_out && _control_out->solo_level() == 0) {
_control_out->mod_solo_level (1);
}
solo_update_disabled = false;
@ -2276,7 +2280,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
}
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->is_master() && !(*i)->is_hidden() && (*i)->soloed()) {
if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
something_soloed = true;
break;
}
@ -2302,7 +2306,7 @@ Session::catch_up_on_solo ()
void
Session::catch_up_on_solo_mute_override ()
{
if (Config->get_solo_model() != InverseMute) {
if (Config->get_solo_model() != SoloInPlace) {
return;
}