X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fio.cc;h=87c03c6b70fafe56440cc694af29a188dcc697ea;hb=481f7c39655afec832ac10430dd61a3bb464aa58;hp=91cbb1cb67e1cf90923c4d8581bcfd7e8c72dbd6;hpb=898fba7b54b19ffddb47fd384c9b04115bc449d9;p=ardour.git diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 91cbb1cb67..87c03c6b70 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -25,7 +25,8 @@ #include -#include +#include + #include #include @@ -54,7 +55,8 @@ extern "C" int isinf (double); using namespace std; using namespace ARDOUR; -//using namespace sigc; +using namespace PBD; + static float current_automation_version_number = 1.0; @@ -63,13 +65,15 @@ const string IO::state_node_name = "IO"; bool IO::connecting_legal = false; bool IO::ports_legal = false; bool IO::panners_legal = false; -sigc::signal IO::GrabPeakPower; +sigc::signal IO::Meter; sigc::signal IO::ConnectingLegal; sigc::signal IO::PortsLegal; sigc::signal IO::PannersLegal; sigc::signal IO::MoreOutputs; sigc::signal IO::PortsCreated; +Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT; + /* this is a default mapper of MIDI control values to a gain coefficient. others can be imagined. see IO::set_midi_to_gain_function(). */ @@ -126,13 +130,20 @@ IO::IO (Session& s, string name, _gain_automation_state = Off; _gain_automation_style = Absolute; - - GrabPeakPower.connect (mem_fun (*this, &IO::grab_peak_power)); + + { + // IO::Meter is emitted from another thread so the + // Meter signal must be protected. + Glib::Mutex::Lock guard (m_meter_signal_lock); + m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter)); + } } IO::~IO () { - LockMonitor lm (io_lock, __LINE__, __FILE__); + + Glib::Mutex::Lock guard (m_meter_signal_lock); + Glib::Mutex::Lock lm (io_lock); vector::iterator i; for (i = _inputs.begin(); i != _inputs.end(); ++i) { @@ -142,6 +153,8 @@ IO::~IO () for (i = _outputs.begin(); i != _outputs.end(); ++i) { _session.engine().unregister_port (*i); } + + m_meter_connection.disconnect(); } void @@ -163,6 +176,8 @@ IO::apply_declick (vector& bufs, uint32_t nbufs, jack_nframes_t nframe double fractional_shift; double fractional_pos; gain_t polscale = invert_polarity ? -1.0f : 1.0f; + + if (nframes == 0) return; fractional_shift = -1.0/declick; @@ -378,7 +393,7 @@ IO::deliver_output (vector& bufs, uint32_t nbufs, jack_nframes_t nfram gain_t pangain = _gain; { - TentativeLockMonitor dm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); if (dm.locked()) { dg = _desired_gain; @@ -425,7 +440,7 @@ IO::deliver_output_no_pan (vector& bufs, uint32_t nbufs, jack_nframes_ } else { - TentativeLockMonitor dm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); if (dm.locked()) { dg = _desired_gain; @@ -566,10 +581,10 @@ IO::disconnect_input (Port* our_port, string other_port, void* src) } { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); /* check that our_port is really one of ours */ @@ -602,10 +617,10 @@ IO::connect_input (Port* our_port, string other_port, void* src) } { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); /* check that our_port is really one of ours */ @@ -636,10 +651,10 @@ IO::disconnect_output (Port* our_port, string other_port, void* src) } { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); if (find (_outputs.begin(), _outputs.end(), our_port) == _outputs.end()) { return -1; @@ -669,10 +684,10 @@ IO::connect_output (Port* our_port, string other_port, void* src) } { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); /* check that our_port is really one of ours */ @@ -728,10 +743,10 @@ IO::remove_output_port (Port* port, void* src) IOChange change (NoChange); { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); if (_noutputs - 1 == (uint32_t) _output_minimum) { /* sorry, you can't do this */ @@ -777,10 +792,10 @@ IO::add_output_port (string destination, void* src) char buf[64]; { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); if (_output_maximum >= 0 && (int) _noutputs == _output_maximum) { return -1; @@ -828,10 +843,10 @@ IO::remove_input_port (Port* port, void* src) IOChange change (NoChange); { - LockMonitor em(_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em(_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); if (((int)_ninputs - 1) < _input_minimum) { /* sorry, you can't do this */ @@ -878,10 +893,10 @@ IO::add_input_port (string source, void* src) char buf[64]; { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); if (_input_maximum >= 0 && (int) _ninputs == _input_maximum) { return -1; @@ -929,10 +944,10 @@ int IO::disconnect_inputs (void* src) { { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); for (vector::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { _session.engine().disconnect (*i); @@ -949,10 +964,10 @@ int IO::disconnect_outputs (void* src) { { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); for (vector::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { _session.engine().disconnect (*i); @@ -1061,8 +1076,8 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src) } { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); + Glib::Mutex::Lock lm (io_lock); Port* port; @@ -1169,11 +1184,11 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src) _session.engine().disconnect (*i); } } - } - - if (in_changed || out_changed) { - setup_peak_meters (); - reset_panner (); + + if (in_changed || out_changed) { + setup_peak_meters (); + reset_panner (); + } } if (out_changed) { @@ -1210,7 +1225,8 @@ IO::ensure_inputs (uint32_t n, bool clear, bool lockit, void* src) } if (lockit) { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); + Glib::Mutex::Lock im (io_lock); changed = ensure_inputs_locked (n, clear, src); } else { changed = ensure_inputs_locked (n, clear, src); @@ -1311,7 +1327,8 @@ IO::ensure_outputs (uint32_t n, bool clear, bool lockit, void* src) /* XXX caller should hold io_lock, but generally doesn't */ if (lockit) { - LockMonitor em (_session.engine().process_lock(), __LINE__, __FILE__); + Glib::Mutex::Lock em (_session.engine().process_lock()); + Glib::Mutex::Lock im (io_lock); changed = ensure_outputs_locked (n, clear, src); } else { changed = ensure_outputs_locked (n, clear, src); @@ -1385,7 +1402,7 @@ IO::state (bool full_state) bool need_ins = true; bool need_outs = true; LocaleGuard lg (X_("POSIX")); - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); node->add_property("name", _name); snprintf (buf, sizeof(buf), "%" PRIu64, id()); @@ -2054,7 +2071,7 @@ IO::set_output_maximum (int n) void IO::set_port_latency (jack_nframes_t nframes) { - LockMonitor lm (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (io_lock); for (vector::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { (*i)->set_latency (nframes); @@ -2105,8 +2122,8 @@ IO::use_input_connection (Connection& c, void* src) uint32_t limit; { - LockMonitor lm (_session.engine().process_lock(), __LINE__, __FILE__); - LockMonitor lm2 (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (_session.engine().process_lock()); + Glib::Mutex::Lock lm2 (io_lock); limit = c.nports(); @@ -2183,8 +2200,8 @@ IO::use_output_connection (Connection& c, void* src) uint32_t limit; { - LockMonitor lm (_session.engine().process_lock(), __LINE__, __FILE__); - LockMonitor lm2 (io_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (_session.engine().process_lock()); + Glib::Mutex::Lock lm2 (io_lock); limit = c.nports(); @@ -2404,7 +2421,7 @@ IO::setup_peak_meters () while (_peak_power.size() < limit) { _peak_power.push_back (0); - _stored_peak_power.push_back (0); + _visible_peak_power.push_back (0); } } @@ -2427,23 +2444,52 @@ IO::state_factory (std::string why) const return state; } +/** + Update the peak meters. + + The meter signal lock is taken to prevent modification of the + Meter signal while updating the meters, taking the meter signal + lock prior to taking the io_lock ensures that all IO will remain + valid while metering. +*/ void -IO::send_state_changed () +IO::update_meters() { - return; + Glib::Mutex::Lock guard (m_meter_signal_lock); + + Meter(); } void -IO::grab_peak_power () +IO::meter () { - LockMonitor lm (io_lock, __LINE__, __FILE__); - + Glib::Mutex::Lock lm (io_lock); // READER: meter thread. uint32_t limit = max (_ninputs, _noutputs); - + for (uint32_t n = 0; n < limit; ++n) { - /* XXX should we use atomic exchange here ? */ - _stored_peak_power[n] = _peak_power[n]; + + /* XXX we should use atomic exchange here */ + + /* grab peak since last read */ + + float new_peak = _peak_power[n]; _peak_power[n] = 0; + + /* compute new visible value using falloff */ + + if (new_peak > 0.0) { + new_peak = coefficient_to_dB (new_peak); + } else { + new_peak = minus_infinity(); + } + + if (_session.meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) { + _visible_peak_power[n] = new_peak; + } else { + // do falloff + new_peak = _visible_peak_power[n] - _session.meter_falloff(); + _visible_peak_power[n] = max (new_peak, -INFINITY); + } } } @@ -2579,7 +2625,7 @@ IO::load_automation (const string& path) void IO::clear_automation () { - LockMonitor lm (automation_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (automation_lock); _gain_automation_curve.clear (); _panner->clear_automation (); } @@ -2590,7 +2636,7 @@ IO::set_gain_automation_state (AutoState state) bool changed = false; { - LockMonitor lm (automation_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (automation_lock); if (state != _gain_automation_curve.automation_state()) { changed = true; @@ -2615,7 +2661,7 @@ IO::set_gain_automation_style (AutoStyle style) bool changed = false; { - LockMonitor lm (automation_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (automation_lock); if (style != _gain_automation_curve.automation_style()) { changed = true; @@ -2643,7 +2689,7 @@ IO::set_gain (gain_t val, void *src) if (val>1.99526231f) val=1.99526231f; { - LockMonitor dm (declick_lock, __LINE__, __FILE__); + Glib::Mutex::Lock dm (declick_lock); _desired_gain = val; }