X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=a322c10068bf81fd9719441440baed3691e5dc1b;hb=bb02870c15a9db3f46e2e24d1d5c72e9ca5dfe0b;hp=2ce7f939b41c8f3040d6174a1040f0c9d6b1377f;hpb=a157537898eccf08009281633b19970515366a78;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 2ce7f939b4..a322c10068 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -20,11 +20,14 @@ #include #include +#include #include #include +#include #include +#include #include #include #include @@ -44,28 +47,28 @@ using namespace std; using namespace ARDOUR; -//using namespace sigc; +using namespace PBD; uint32_t Route::order_key_cnt = 0; -Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg) - : IO (sess, name, input_min, input_max, output_min, output_max), +Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type) + : IO (sess, name, input_min, input_max, output_min, output_max, default_type), _flags (flg), - _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()), - _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port()) + _solo_control (X_("solo"), *this, ToggleControllable::SoloControl), + _mute_control (X_("mute"), *this, ToggleControllable::MuteControl) { init (); } -Route::Route (Session& sess, const XMLNode& node) - : IO (sess, "route"), - _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()), - _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port()) +Route::Route (Session& sess, const XMLNode& node, DataType default_type) + : IO (sess, *node.child ("IO"), default_type), + _solo_control (X_("solo"), *this, ToggleControllable::SoloControl), + _mute_control (X_("mute"), *this, ToggleControllable::MuteControl) { init (); - set_state (node); + _set_state (node, false); } void @@ -87,7 +90,8 @@ Route::init () _declickable = false; _pending_declick = true; _remote_control_id = 0; - + _ignore_gain_on_deliver = true; + _edit_group = 0; _mix_group = 0; @@ -105,13 +109,10 @@ Route::init () input_changed.connect (mem_fun (this, &Route::input_change_handler)); output_changed.connect (mem_fun (this, &Route::output_change_handler)); - - reset_midi_control (_session.midi_port(), _session.get_midi_control()); } Route::~Route () { - GoingAway (); /* EMIT SIGNAL */ clear_redirects (this); if (_control_outs) { @@ -216,8 +217,8 @@ Route::set_gain (gain_t val, void *src) void Route::process_output_buffers (vector& bufs, uint32_t nbufs, - jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, + nframes_t start_frame, nframes_t end_frame, + nframes_t nframes, nframes_t offset, bool with_redirects, int declick, bool meter) { uint32_t n; @@ -229,13 +230,22 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, IO *co; bool mute_audible; bool solo_audible; - bool no_monitor = (Config->get_use_hardware_monitoring() || !Config->get_use_sw_monitoring ()); + bool no_monitor; gain_t* gab = _session.gain_automation_buffer(); + switch (Config->get_monitoring_model()) { + case HardwareMonitoring: + case ExternalMonitoring: + no_monitor = true; + break; + default: + no_monitor = false; + } + declick = _pending_declick; { - TentativeLockMonitor cm (control_outs_lock, __LINE__, __FILE__); + Glib::Mutex::Lock cm (control_outs_lock, Glib::TRY_LOCK); if (cm.locked()) { co = _control_outs; @@ -245,7 +255,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } { - TentativeLockMonitor dm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); if (dm.locked()) { dmg = desired_mute_gain; @@ -263,17 +273,17 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, -------------------------------------------------------------------------------------------------- */ if (declick > 0) { - apply_declick (bufs, nbufs, nframes, 0.0, 1.0, _phase_invert); + apply_declick (bufs, nbufs, nframes, 0.0, 1.0, false); _pending_declick = 0; } else if (declick < 0) { - apply_declick (bufs, nbufs, nframes, 1.0, 0.0, _phase_invert); + apply_declick (bufs, nbufs, nframes, 1.0, 0.0, false); _pending_declick = 0; } else { /* no global declick */ if (solo_gain != dsg) { - apply_declick (bufs, nbufs, nframes, solo_gain, dsg, _phase_invert); + apply_declick (bufs, nbufs, nframes, solo_gain, dsg, false); solo_gain = dsg; } } @@ -290,7 +300,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) { - apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert); + apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -312,7 +322,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, // TODO: this is probably wrong - (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) + (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) ) { @@ -330,13 +340,19 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, -------------------------------------------------------------------------------------------------- */ if (with_redirects) { - TentativeRWLockMonitor rm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK); if (rm.locked()) { if (mute_gain > 0 || !_mute_affects_pre_fader) { for (i = _redirects.begin(); i != _redirects.end(); ++i) { switch ((*i)->placement()) { case PreFader: - (*i)->run (bufs, nbufs, nframes, offset); + if (dsg == 0) { + if (boost::dynamic_pointer_cast(*i) || boost::dynamic_pointer_cast(*i)) { + (*i)->silence (nframes, offset); + } + } else { + (*i)->run (bufs, nbufs, nframes, offset); + } break; case PostFader: post_fader_work = true; @@ -360,7 +376,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) { - apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert); + apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -391,7 +407,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, // rec-enabled but not s/w monitoring - (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) + (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) ) { @@ -418,11 +434,11 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, // h/w monitoring not in use - (!Config->get_use_hardware_monitoring() && + (!Config->get_monitoring_model() == HardwareMonitoring && // AND software monitoring required - Config->get_use_sw_monitoring())) { + Config->get_monitoring_model() == SoftwareMonitoring)) { if (apply_gain_automation) { @@ -430,7 +446,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, for (n = 0; n < nbufs; ++n) { Sample *sp = bufs[n]; - for (jack_nframes_t nx = 0; nx < nframes; ++nx) { + for (nframes_t nx = 0; nx < nframes; ++nx) { sp[nx] *= -gab[nx]; } } @@ -438,7 +454,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, for (n = 0; n < nbufs; ++n) { Sample *sp = bufs[n]; - for (jack_nframes_t nx = 0; nx < nframes; ++nx) { + for (nframes_t nx = 0; nx < nframes; ++nx) { sp[nx] *= gab[nx]; } } @@ -475,7 +491,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, for (n = 0; n < nbufs; ++n) { Sample *sp = bufs[n]; - apply_gain_to_buffer(sp,nframes,this_gain); + Session::apply_gain_to_buffer(sp,nframes,this_gain); } } else if (_gain == 0) { @@ -499,7 +515,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, if (post_fader_work) { - TentativeRWLockMonitor rm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK); if (rm.locked()) { if (mute_gain > 0 || !_mute_affects_post_fader) { for (i = _redirects.begin(); i != _redirects.end(); ++i) { @@ -507,7 +523,13 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, case PreFader: break; case PostFader: - (*i)->run (bufs, nbufs, nframes, offset); + if (dsg == 0) { + if (boost::dynamic_pointer_cast(*i) || boost::dynamic_pointer_cast(*i)) { + (*i)->silence (nframes, offset); + } + } else { + (*i)->run (bufs, nbufs, nframes, offset); + } break; } } @@ -526,7 +548,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) { - apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert); + apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -540,9 +562,6 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, solo_audible = solo_gain > 0; mute_audible = dmg > 0 || !_mute_affects_control_outs; - cerr << _name << " have control outs, solo audible = " << solo_audible << " mute audible = " << mute_audible - << endl; - if ( // silent anyway (_gain == 0 && !apply_gain_automation) || @@ -557,7 +576,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, // recording but not s/w monitoring - (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) + (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) ) { @@ -574,7 +593,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, ----------------------------------------------------------------------*/ if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) { - apply_declick (bufs, nbufs, nframes, mute_gain, dmg, _phase_invert); + apply_declick (bufs, nbufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -590,7 +609,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, /* relax */ - } else if (no_monitor && record_enabled() && (!_session.get_auto_input() || _session.actively_recording())) { + } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) { IO::silence (nframes, offset); @@ -602,7 +621,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, // muted by solo of another track, but not using control outs for solo - (!solo_audible && (_session.solo_model() != Session::SoloBus)) || + (!solo_audible && (Config->get_solo_model() != SoloBus)) || // muted by mute of this track @@ -622,7 +641,9 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } else { - if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) { + if ((_session.transport_speed() > 1.5f || + _session.transport_speed() < -1.5f) && + Config->get_quieten_at_speed()) { pan (bufs, nbufs, nframes, offset, speed_quietning); } else { // cerr << _name << " panner state = " << _panner->automation_state() << endl; @@ -667,7 +688,7 @@ Route::n_process_buffers () void -Route::passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_first) +Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first) { vector& bufs = _session.get_passthru_buffers(); uint32_t limit = n_process_buffers (); @@ -715,18 +736,15 @@ Route::set_solo (bool yn, void *src) if (_soloed != yn) { _soloed = yn; - solo_changed (src); /* EMIT SIGNAL */ - - if (_session.get_midi_feedback()) { - _midi_solo_control.send_feedback (_soloed); - } + solo_changed (src); /* EMIT SIGNAL */ + _solo_control.Changed (); /* EMIT SIGNAL */ } } void Route::set_solo_mute (bool yn) { - LockMonitor lm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (declick_lock); /* Called by Session in response to another Route being soloed. */ @@ -756,17 +774,15 @@ Route::set_mute (bool yn, void *src) _muted = yn; mute_changed (src); /* EMIT SIGNAL */ - if (_session.get_midi_feedback()) { - _midi_mute_control.send_feedback (_muted); - } + _mute_control.Changed (); /* EMIT SIGNAL */ - LockMonitor lm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (declick_lock); desired_mute_gain = (yn?0.0f:1.0f); } } int -Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) +Route::add_redirect (boost::shared_ptr redirect, void *src, uint32_t* err_streams) { uint32_t old_rmo = redirect_max_outs; @@ -775,14 +791,14 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) } { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); - PluginInsert* pi; - PortInsert* porti; + boost::shared_ptr pi; + boost::shared_ptr porti; uint32_t potential_max_streams = 0; - if ((pi = dynamic_cast(redirect)) != 0) { + if ((pi = boost::dynamic_pointer_cast(redirect)) != 0) { pi->set_count (1); if (pi->input_streams() == 0) { @@ -791,8 +807,8 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) } potential_max_streams = max(pi->input_streams(), pi->output_streams()); - - } else if ((porti = dynamic_cast(redirect)) != 0) { + + } else if ((porti = boost::dynamic_pointer_cast(redirect)) != 0) { /* force new port inserts to start out with an i/o configuration that matches this route's i/o configuration. @@ -814,7 +830,10 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) _peak_power.push_back(0); } while (_visible_peak_power.size() < potential_max_streams) { - _visible_peak_power.push_back(0); + _visible_peak_power.push_back(-INFINITY); + } + while (_max_peak_power.size() < potential_max_streams) { + _max_peak_power.push_back(-INFINITY); } _redirects.push_back (redirect); @@ -848,7 +867,7 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea } { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); RedirectList::iterator existing_end = _redirects.end(); --existing_end; @@ -857,9 +876,9 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) { - PluginInsert* pi; + boost::shared_ptr pi; - if ((pi = dynamic_cast(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { pi->set_count (1); uint32_t m = max(pi->input_streams(), pi->output_streams()); @@ -872,7 +891,10 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea _peak_power.push_back(0); } while (_visible_peak_power.size() < potential_max_streams) { - _visible_peak_power.push_back(0); + _visible_peak_power.push_back(-INFINITY); + } + while (_max_peak_power.size() < potential_max_streams) { + _max_peak_power.push_back(-INFINITY); } _redirects.push_back (*i); @@ -907,12 +929,11 @@ Route::clear_redirects (void *src) } { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); - - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - delete *i; + Glib::RWLock::WriterLock lm (redirect_lock); + RedirectList::iterator i; + for (i = _redirects.begin(); i != _redirects.end(); ++i) { + (*i)->drop_references (); } - _redirects.clear (); } @@ -926,7 +947,7 @@ Route::clear_redirects (void *src) } int -Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) +Route::remove_redirect (boost::shared_ptr redirect, void *src, uint32_t* err_streams) { uint32_t old_rmo = redirect_max_outs; @@ -937,7 +958,7 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) redirect_max_outs = 0; { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); RedirectList::iterator i; bool removed = false; @@ -958,13 +979,13 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) run. */ - Send* send; - PortInsert* port_insert; + boost::shared_ptr send; + boost::shared_ptr port_insert; - if ((send = dynamic_cast (*i)) != 0) { + if ((send = boost::dynamic_pointer_cast (*i)) != 0) { send->disconnect_inputs (this); send->disconnect_outputs (this); - } else if ((port_insert = dynamic_cast (*i)) != 0) { + } else if ((port_insert = boost::dynamic_pointer_cast (*i)) != 0) { port_insert->disconnect_inputs (this); port_insert->disconnect_outputs (this); } @@ -993,9 +1014,9 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) bool foo = false; for (i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - - if ((pi = dynamic_cast(*i)) != 0) { + boost::shared_ptr pi; + + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { if (pi->is_generator()) { foo = true; } @@ -1009,6 +1030,8 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) reset_panner (); } + redirect->drop_references (); + redirects_changed (src); /* EMIT SIGNAL */ return 0; } @@ -1016,7 +1039,7 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) int Route::reset_plugin_counts (uint32_t* lpc) { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); return _reset_plugin_counts (lpc); } @@ -1028,7 +1051,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams) uint32_t i_cnt; uint32_t s_cnt; map > insert_map; - jack_nframes_t initial_streams; + nframes_t initial_streams; redirect_max_outs = 0; i_cnt = 0; @@ -1042,7 +1065,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams) for (r = _redirects.begin(); r != _redirects.end(); ++r) { - Insert *insert; + boost::shared_ptr insert; /* do this here in case we bomb out before we get to the end of this function. @@ -1050,22 +1073,22 @@ Route::_reset_plugin_counts (uint32_t* err_streams) redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs); - if ((insert = dynamic_cast(*r)) != 0) { + if ((insert = boost::dynamic_pointer_cast(*r)) != 0) { ++i_cnt; - insert_map[insert->placement()].push_back (InsertCount (*insert)); + insert_map[insert->placement()].push_back (InsertCount (insert)); /* reset plugin counts back to one for now so that we have a predictable, controlled state to try to configure. */ - PluginInsert* pi; + boost::shared_ptr pi; - if ((pi = dynamic_cast(insert)) != 0) { + if ((pi = boost::dynamic_pointer_cast(insert)) != 0) { pi->set_count (1); } - } else if (dynamic_cast (*r) != 0) { + } else if (boost::dynamic_pointer_cast (*r) != 0) { ++s_cnt; } } @@ -1092,7 +1115,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams) if (!insert_map[PreFader].empty()) { InsertCount& ic (insert_map[PreFader].back()); - initial_streams = ic.insert.compute_output_streams (ic.cnt); + initial_streams = ic.insert->compute_output_streams (ic.cnt); } else { initial_streams = n_inputs (); } @@ -1116,9 +1139,9 @@ Route::_reset_plugin_counts (uint32_t* err_streams) RedirectList::iterator prev = _redirects.end(); for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) { - Send* s; + boost::shared_ptr s; - if ((s = dynamic_cast (*r)) != 0) { + if ((s = boost::dynamic_pointer_cast (*r)) != 0) { if (r == _redirects.begin()) { s->expect_inputs (n_inputs()); } else { @@ -1141,11 +1164,11 @@ Route::apply_some_plugin_counts (list& iclist) for (i = iclist.begin(); i != iclist.end(); ++i) { - if ((*i).insert.configure_io ((*i).cnt, (*i).in, (*i).out)) { + if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) { return -1; } /* make sure that however many we have, they are all active */ - (*i).insert.activate (); + (*i).insert->activate (); } return 0; @@ -1158,7 +1181,7 @@ Route::check_some_plugin_counts (list& iclist, int32_t required_inp for (i = iclist.begin(); i != iclist.end(); ++i) { - if (((*i).cnt = (*i).insert.can_support_input_configuration (required_inputs)) < 0) { + if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) { if (err_streams) { *err_streams = required_inputs; } @@ -1166,7 +1189,7 @@ Route::check_some_plugin_counts (list& iclist, int32_t required_inp } (*i).in = required_inputs; - (*i).out = (*i).insert.compute_output_streams ((*i).cnt); + (*i).out = (*i).insert->compute_output_streams ((*i).cnt); required_inputs = (*i).out; } @@ -1186,7 +1209,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st RedirectList to_be_deleted; { - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); RedirectList::iterator tmp; RedirectList the_copy; @@ -1210,7 +1233,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) { if ((*i)->placement() == placement) { - _redirects.push_back (Redirect::clone (**i)); + _redirects.push_back (Redirect::clone (*i)); } } @@ -1228,7 +1251,6 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st ++tmp; if ((*i)->placement() == placement) { - delete *i; _redirects.erase (i); } @@ -1247,10 +1269,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st } else { /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */ - - for (RedirectList::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) { - delete *i; - } + to_be_deleted.clear (); } } @@ -1265,7 +1284,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st void Route::all_redirects_flip () { - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock); if (_redirects.empty()) { return; @@ -1281,7 +1300,7 @@ Route::all_redirects_flip () void Route::all_redirects_active (bool state) { - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock); if (_redirects.empty()) { return; @@ -1293,7 +1312,7 @@ Route::all_redirects_active (bool state) } struct RedirectSorter { - bool operator() (const Redirect *a, const Redirect *b) { + bool operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->sort_key() < b->sort_key(); } }; @@ -1303,7 +1322,7 @@ Route::sort_redirects (uint32_t* err_streams) { { RedirectSorter comparator; - RWLockMonitor lm (redirect_lock, true, __LINE__, __FILE__); + Glib::RWLock::WriterLock lm (redirect_lock); uint32_t old_rmo = redirect_max_outs; /* the sweet power of C++ ... */ @@ -1341,14 +1360,15 @@ XMLNode& Route::state(bool full_state) { XMLNode *node = new XMLNode("Route"); - XMLNode *aevents; RedirectList:: iterator i; char buf[32]; if (_flags) { - snprintf (buf, sizeof (buf), "0x%x", _flags); - node->add_property("flags", buf); + node->add_property("flags", enum_2_string (_flags)); } + + node->add_property("default-type", _default_type.to_string()); + node->add_property("active", _active?"yes":"no"); node->add_property("muted", _muted?"yes":"no"); node->add_property("soloed", _soloed?"yes":"no"); @@ -1365,26 +1385,6 @@ Route::state(bool full_state) node->add_property("mix-group", _mix_group->name()); } - /* MIDI control */ - - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte additional; - XMLNode* midi_node = 0; - XMLNode* child; - - midi_node = node->add_child ("MIDI"); - - if (_midi_mute_control.get_control_info (chn, ev, additional)) { - child = midi_node->add_child ("mute"); - set_midi_node_info (child, ev, chn, additional); - } - if (_midi_solo_control.get_control_info (chn, ev, additional)) { - child = midi_node->add_child ("solo"); - set_midi_node_info (child, ev, chn, additional); - } - - string order_string; OrderKeys::iterator x = order_keys.begin(); @@ -1405,6 +1405,8 @@ Route::state(bool full_state) node->add_property ("order-keys", order_string); node->add_child_nocopy (IO::state (full_state)); + node->add_child_nocopy (_solo_control.get_state ()); + node->add_child_nocopy (_mute_control.get_state ()); if (_control_outs) { XMLNode* cnode = new XMLNode (X_("ControlOuts")); @@ -1417,26 +1419,6 @@ Route::state(bool full_state) cmt->add_content (_comment); } - if (full_state) { - string path; - - path = _session.snap_name(); - path += "-gain-"; - path += legalize_for_path (_name); - path += ".automation"; - - /* XXX we didn't ask for a state save, we asked for the current state. - FIX ME! - */ - - if (save_automation (path)) { - error << _("Could not get state of route. Problem with save_automation") << endmsg; - } - - aevents = node->add_child ("Automation"); - aevents->add_property ("path", path); - } - for (i = _redirects.begin(); i != _redirects.end(); ++i) { node->add_child_nocopy((*i)->state (full_state)); } @@ -1472,13 +1454,13 @@ void Route::add_redirect_from_xml (const XMLNode& node) { const XMLProperty *prop; - Insert *insert = 0; - Send *send = 0; if (node.name() == "Send") { + try { - send = new Send (_session, node); + boost::shared_ptr send (new Send (_session, node)); + add_redirect (send, this); } catch (failed_constructor &err) { @@ -1486,21 +1468,21 @@ Route::add_redirect_from_xml (const XMLNode& node) return; } - add_redirect (send, this); - } else if (node.name() == "Insert") { try { if ((prop = node.property ("type")) != 0) { + boost::shared_ptr insert; + if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") { - insert = new PluginInsert(_session, node); + insert.reset (new PluginInsert(_session, node)); } else if (prop->value() == "port") { - insert = new PortInsert (_session, node); + insert.reset (new PortInsert (_session, node)); } else { @@ -1523,37 +1505,44 @@ Route::add_redirect_from_xml (const XMLNode& node) int Route::set_state (const XMLNode& node) +{ + return _set_state (node, true); +} + +int +Route::_set_state (const XMLNode& node, bool call_base) { XMLNodeList nlist; XMLNodeConstIterator niter; XMLNode *child; XMLPropertyList plist; const XMLProperty *prop; - XMLNodeList midi_kids; - if (node.name() != "Route"){ error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg; return -1; } - if ((prop = node.property ("flags")) != 0) { - int x; - sscanf (prop->value().c_str(), "0x%x", &x); - _flags = Flag (x); + if ((prop = node.property (X_("flags"))) != 0) { + _flags = Flag (string_2_enum (prop->value(), _flags)); } else { _flags = Flag (0); } + + if ((prop = node.property (X_("default-type"))) != 0) { + _default_type = DataType(prop->value()); + assert(_default_type != DataType::NIL); + } - if ((prop = node.property ("phase-invert")) != 0) { + if ((prop = node.property (X_("phase-invert"))) != 0) { set_phase_invert(prop->value()=="yes"?true:false, this); } - if ((prop = node.property ("active")) != 0) { + if ((prop = node.property (X_("active"))) != 0) { set_active (prop->value() == "yes"); } - if ((prop = node.property ("muted")) != 0) { + if ((prop = node.property (X_("muted"))) != 0) { bool yn = prop->value()=="yes"?true:false; /* force reset of mute status */ @@ -1563,7 +1552,7 @@ Route::set_state (const XMLNode& node) mute_gain = desired_mute_gain; } - if ((prop = node.property ("soloed")) != 0) { + if ((prop = node.property (X_("soloed"))) != 0) { bool yn = prop->value()=="yes"?true:false; /* force reset of solo status */ @@ -1573,23 +1562,23 @@ Route::set_state (const XMLNode& node) solo_gain = desired_solo_gain; } - if ((prop = node.property ("mute-affects-pre-fader")) != 0) { + if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) { _mute_affects_pre_fader = (prop->value()=="yes")?true:false; } - if ((prop = node.property ("mute-affects-post-fader")) != 0) { + if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) { _mute_affects_post_fader = (prop->value()=="yes")?true:false; } - if ((prop = node.property ("mute-affects-control-outs")) != 0) { + if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) { _mute_affects_control_outs = (prop->value()=="yes")?true:false; } - if ((prop = node.property ("mute-affects-main-outs")) != 0) { + if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) { _mute_affects_main_outs = (prop->value()=="yes")?true:false; } - if ((prop = node.property ("edit-group")) != 0) { + if ((prop = node.property (X_("edit-group"))) != 0) { RouteGroup* edit_group = _session.edit_group_by_name(prop->value()); if(edit_group == 0) { error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; @@ -1598,7 +1587,7 @@ Route::set_state (const XMLNode& node) } } - if ((prop = node.property ("order-keys")) != 0) { + if ((prop = node.property (X_("order-keys"))) != 0) { long n; @@ -1635,7 +1624,7 @@ Route::set_state (const XMLNode& node) delete deferred_state; } - deferred_state = new XMLNode("deferred state"); + deferred_state = new XMLNode(X_("deferred state")); /* set parent class properties before anything else */ @@ -1643,7 +1632,7 @@ Route::set_state (const XMLNode& node) child = *niter; - if (child->name() == IO::state_node_name) { + if (child->name() == IO::state_node_name && call_base) { IO::set_state (*child); break; @@ -1654,7 +1643,7 @@ Route::set_state (const XMLNode& node) child = *niter; - if (child->name() == "Send") { + if (child->name() == X_("Send")) { if (!IO::ports_legal) { @@ -1665,7 +1654,7 @@ Route::set_state (const XMLNode& node) add_redirect_from_xml (*child); } - } else if (child->name() == "Insert") { + } else if (child->name() == X_("Insert")) { if (!IO::ports_legal) { @@ -1676,21 +1665,13 @@ Route::set_state (const XMLNode& node) add_redirect_from_xml (*child); } - } else if (child->name() == "Automation") { - - XMLPropertyList plist; - XMLPropertyConstIterator piter; - XMLProperty *prop; + } else if (child->name() == X_("Automation")) { - plist = child->properties(); - for (piter = plist.begin(); piter != plist.end(); ++piter) { - prop = *piter; - if (prop->name() == "path") { - load_automation (prop->value()); - } + if ((prop = child->property (X_("path"))) != 0) { + load_automation (prop->value()); } - } else if (child->name() == "ControlOuts") { + } else if (child->name() == X_("ControlOuts")) { string coutname = _name; coutname += _("[control]"); @@ -1698,19 +1679,25 @@ Route::set_state (const XMLNode& node) _control_outs = new IO (_session, coutname); _control_outs->set_state (**(child->children().begin())); - } else if (child->name() == "Comment") { + } else if (child->name() == X_("Comment")) { /* XXX this is a terrible API design in libxml++ */ XMLNode *cmt = *(child->children().begin()); _comment = cmt->content(); - } else if (child->name() == "extra") { + } else if (child->name() == X_("extra")) { _extra_xml = new XMLNode (*child); + } else if (child->name() == X_("solo")) { + _solo_control.set_state (*child); + _session.add_controllable (&_solo_control); + } else if (child->name() == X_("mute")) { + _mute_control.set_state (*child); + _session.add_controllable (&_mute_control); } } - if ((prop = node.property ("mix-group")) != 0) { + if ((prop = node.property (X_("mix-group"))) != 0) { RouteGroup* mix_group = _session.mix_group_by_name(prop->value()); if (mix_group == 0) { error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; @@ -1719,45 +1706,6 @@ Route::set_state (const XMLNode& node) } } - midi_kids = node.children ("MIDI"); - - for (niter = midi_kids.begin(); niter != midi_kids.end(); ++niter) { - - XMLNodeList kids; - XMLNodeConstIterator miter; - XMLNode* child; - - kids = (*niter)->children (); - - for (miter = kids.begin(); miter != kids.end(); ++miter) { - - child =* miter; - - MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */ - MIDI::byte additional = 0; /* ditto */ - MIDI::channel_t chn = 0; /* ditto */ - - if (child->name() == "mute") { - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_mute_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - else if (child->name() == "solo") { - - if (get_midi_node_info (child, ev, chn, additional)) { - _midi_solo_control.set_control_type (chn, ev, additional); - } else { - error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg; - } - } - - } - } - - return 0; } @@ -1769,7 +1717,7 @@ Route::curve_reallocate () } void -Route::silence (jack_nframes_t nframes, jack_nframes_t offset) +Route::silence (nframes_t nframes, nframes_t offset) { if (!_silent) { @@ -1782,12 +1730,12 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset) } { - TentativeRWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK); if (lm.locked()) { for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - if (!_active && (pi = dynamic_cast (*i)) != 0) { + boost::shared_ptr pi; + if (!_active && (pi = boost::dynamic_pointer_cast (*i)) != 0) { // skip plugins, they don't need anything when we're not active continue; } @@ -1807,7 +1755,7 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset) int Route::set_control_outs (const vector& ports) { - LockMonitor lm (control_outs_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (control_outs_lock); vector::const_iterator i; if (_control_outs) { @@ -1898,18 +1846,17 @@ Route::set_comment (string cmt, void *src) } bool -Route::feeds (Route *o) +Route::feeds (boost::shared_ptr other) { uint32_t i, j; - IO& other = *o; IO& self = *this; uint32_t no = self.n_outputs(); - uint32_t ni = other.n_inputs (); + uint32_t ni = other->n_inputs (); for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if (self.output(i)->connected_to (other.input(j)->name())) { + if (self.output(i)->connected_to (other->input(j)->name())) { return true; } } @@ -1923,7 +1870,7 @@ Route::feeds (Route *o) for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if ((*r)->output(i)->connected_to (other.input (j)->name())) { + if ((*r)->output(i)->connected_to (other->input (j)->name())) { return true; } } @@ -1938,7 +1885,7 @@ Route::feeds (Route *o) for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if (_control_outs->output(i)->connected_to (other.input (j)->name())) { + if (_control_outs->output(i)->connected_to (other->input (j)->name())) { return true; } } @@ -2005,12 +1952,12 @@ Route::set_active (bool yn) } void -Route::transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects) +Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_redirects) { - jack_nframes_t now = _session.transport_frame(); + nframes_t now = _session.transport_frame(); { - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock); if (!did_locate) { automation_snapshot (now); @@ -2032,19 +1979,6 @@ Route::transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_re _roll_delay = _initial_delay; } -UndoAction -Route::get_memento() const -{ - void (Route::*pmf)(state_id_t) = &Route::set_state; - return sigc::bind (mem_fun (*(const_cast(this)), pmf), _current_state_id); -} - -void -Route::set_state (state_id_t id) -{ - return; -} - void Route::input_change_handler (IOChange change, void *ignored) { @@ -2076,7 +2010,7 @@ Route::pans_required () const } int -Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, +Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, bool session_state_changing, bool can_record, bool rec_monitors_input) { if (n_outputs() == 0) { @@ -2099,8 +2033,8 @@ Route::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes return 0; } -jack_nframes_t -Route::check_initial_delay (jack_nframes_t nframes, jack_nframes_t& offset, jack_nframes_t& transport_frame) +nframes_t +Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame) { if (_roll_delay > nframes) { @@ -2125,24 +2059,24 @@ Route::check_initial_delay (jack_nframes_t nframes, jack_nframes_t& offset, jack } int -Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick, +Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick, bool can_record, bool rec_monitors_input) { { - TentativeRWLockMonitor lm(redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK); if (lm.locked()) { // automation snapshot can also be called from the non-rt context // and it uses the redirect list, so we take the lock out here automation_snapshot (_session.transport_frame()); } } - + if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) { silence (nframes, offset); return 0; } - jack_nframes_t unused = 0; + nframes_t unused = 0; if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) { return 0; @@ -2153,11 +2087,11 @@ Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t apply_gain_automation = false; { - TentativeLockMonitor am (automation_lock, __LINE__, __FILE__); + Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK); if (am.locked() && _session.transport_rolling()) { - jack_nframes_t start_frame = end_frame - nframes; + nframes_t start_frame = end_frame - nframes; if (gain_automation_playback()) { apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes); @@ -2171,7 +2105,7 @@ Route::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t } int -Route::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, +Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, bool can_record, bool rec_monitors_input) { silence (nframes, offset); @@ -2182,17 +2116,17 @@ void Route::toggle_monitor_input () { for (vector::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - (*i)->request_monitor_input(!(*i)->monitoring_input()); + (*i)->ensure_monitor_input(!(*i)->monitoring_input()); } } bool Route::has_external_redirects () const { - const PortInsert* pi; + boost::shared_ptr pi; for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - if ((pi = dynamic_cast(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { uint32_t no = pi->n_outputs(); @@ -2213,67 +2147,6 @@ Route::has_external_redirects () const return false; } -void -Route::reset_midi_control (MIDI::Port* port, bool on) -{ - MIDI::channel_t chn; - MIDI::eventType ev; - MIDI::byte extra; - - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->reset_midi_control (port, on); - } - - IO::reset_midi_control (port, on); - - _midi_solo_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_solo_control.midi_rebind (port, chn); - - _midi_mute_control.get_control_info (chn, ev, extra); - if (!on) { - chn = -1; - } - _midi_mute_control.midi_rebind (port, chn); -} - -void -Route::send_all_midi_feedback () -{ - if (_session.get_midi_feedback()) { - - { - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->send_all_midi_feedback (); - } - } - - IO::send_all_midi_feedback(); - - _midi_solo_control.send_feedback (_soloed); - _midi_mute_control.send_feedback (_muted); - } -} - -MIDI::byte* -Route::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize) -{ - buf = _midi_solo_control.write_feedback (buf, bufsize, _soloed); - buf = _midi_mute_control.write_feedback (buf, bufsize, _muted); - - { - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - buf = (*i)->write_midi_feedback (buf, bufsize); - } - } - - return IO::write_midi_feedback (buf, bufsize); -} - void Route::flush_redirects () { @@ -2281,7 +2154,7 @@ Route::flush_redirects () this is called from the RT audio thread. */ - RWLockMonitor lm (redirect_lock, false, __LINE__, __FILE__); + Glib::RWLock::ReaderLock lm (redirect_lock); for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { (*i)->deactivate (); @@ -2299,7 +2172,7 @@ Route::set_meter_point (MeterPoint p, void *src) } } -jack_nframes_t +nframes_t Route::update_total_latency () { _own_latency = 0; @@ -2325,7 +2198,7 @@ Route::update_total_latency () } void -Route::set_latency_delay (jack_nframes_t longest_session_latency) +Route::set_latency_delay (nframes_t longest_session_latency) { _initial_delay = longest_session_latency - _own_latency; @@ -2335,7 +2208,7 @@ Route::set_latency_delay (jack_nframes_t longest_session_latency) } void -Route::automation_snapshot (jack_nframes_t now) +Route::automation_snapshot (nframes_t now) { IO::automation_snapshot (now); @@ -2344,110 +2217,50 @@ Route::automation_snapshot (jack_nframes_t now) } } -Route::MIDIToggleControl::MIDIToggleControl (Route& s, ToggleType tp, MIDI::Port* port) - : MIDI::Controllable (port, true), route (s), type(tp), setting(false) +Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp) + : Controllable (name), route (s), type(tp) { - last_written = false; /* XXX need a good out-of-bound-value */ + } void -Route::MIDIToggleControl::set_value (float val) +Route::ToggleControllable::set_value (float val) { - MIDI::eventType et; - MIDI::channel_t chn; - MIDI::byte additional; - - get_control_info (chn, et, additional); - - setting = true; - -#ifdef HOLD_TOGGLE_VALUES - if (et == MIDI::off || et == MIDI::on) { - - /* literal toggle */ - - switch (type) { - case MuteControl: - route.set_mute (!route.muted(), this); - break; - case SoloControl: - route.set_solo (!route.soloed(), this); - break; - default: - break; - } - - } else { -#endif - - /* map full control range to a boolean */ - - bool bval = ((val >= 0.5f) ? true: false); - - switch (type) { - case MuteControl: - route.set_mute (bval, this); - break; - case SoloControl: - route.set_solo (bval, this); - break; - default: - break; - } - -#ifdef HOLD_TOGGLE_VALUES + bool bval = ((val >= 0.5f) ? true: false); + + switch (type) { + case MuteControl: + route.set_mute (bval, this); + break; + case SoloControl: + route.set_solo (bval, this); + break; + default: + break; } -#endif - - setting = false; } -void -Route::MIDIToggleControl::send_feedback (bool value) +float +Route::ToggleControllable::get_value (void) const { - - if (!setting && get_midi_feedback()) { - MIDI::byte val = (MIDI::byte) (value ? 127: 0); - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - MIDI::EventTwoBytes data; - - if (get_control_info (ch, ev, additional)) { - data.controller_number = additional; - data.value = val; - last_written = value; - - route._session.send_midi_message (get_port(), ev, ch, data); - } - } + float val = 0.0f; -} - -MIDI::byte* -Route::MIDIToggleControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force) -{ - if (get_midi_feedback() && bufsize > 2) { - MIDI::channel_t ch = 0; - MIDI::eventType ev = MIDI::none; - MIDI::byte additional = 0; - - if (get_control_info (ch, ev, additional)) { - if (val != last_written || force) { - *buf++ = (0xF0 & ev) | (0xF & ch); - *buf++ = additional; /* controller number */ - *buf++ = (MIDI::byte) (val ? 127 : 0); - bufsize -= 3; - last_written = val; - } - } + switch (type) { + case MuteControl: + val = route.muted() ? 1.0f : 0.0f; + break; + case SoloControl: + val = route.soloed() ? 1.0f : 0.0f; + break; + default: + break; } - return buf; + return val; } void -Route::set_block_size (jack_nframes_t nframes) +Route::set_block_size (nframes_t nframes) { for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { (*i)->set_block_size (nframes); @@ -2482,8 +2295,8 @@ Route::protect_automation () } for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - if ((pi = dynamic_cast (*i)) != 0) { + boost::shared_ptr pi; + if ((pi = boost::dynamic_pointer_cast (*i)) != 0) { pi->protect_automation (); } }