#include "ardour/logmeter.h" #include "ardour/audioengine.h" #include #include #include "widgets/fastmeter.h" #include "gui_thread.h" #include "livetrax_meters.h" #include "ui_config.h" using namespace ARDOUR; using namespace ArdourWidgets; #define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ())) LiveTraxMeters::LiveTraxMeters () { set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER); Gtk::Alignment* container = manage (new Gtk::Alignment (.5, .5, 0, 0)); _meter_box.set_border_width (PX_SCALE (0)); _meter_box.set_spacing (PX_SCALE (10)); container->add (_meter_box); container->show (); add (*container); Gtk::Viewport *vp = dynamic_cast (get_child()); vp->set_shadow_type(Gtk::SHADOW_NONE); AudioEngine::instance ()->Running.connect (_engine_connections, invalidator (*this), std::bind (&LiveTraxMeters::start_updating, this), gui_context ()); AudioEngine::instance ()->Stopped.connect (_engine_connections, invalidator (*this), std::bind (&LiveTraxMeters::stop_updating, this), gui_context ()); AudioEngine::instance ()->Halted.connect (_engine_connections, invalidator (*this), std::bind (&LiveTraxMeters::stop_updating, this), gui_context ()); if (ARDOUR::AudioEngine::instance ()->running ()) { start_updating (); } } LiveTraxMeters::~LiveTraxMeters () { } void LiveTraxMeters::start_updating () { resize (AudioEngine::instance ()->audio_input_ports ().size ()); _fast_screen_update_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &LiveTraxMeters::update_meters), 40, GDK_PRIORITY_REDRAW + 10); } void LiveTraxMeters::stop_updating () { _fast_screen_update_connection.disconnect (); resize (0); } void LiveTraxMeters::resize (size_t sz) { size_t old = _meters.size(); while (old > sz) { /* Widgets are all managed so this should delete them as they are removed. */ _meter_box.remove (*_widgets[old - 1]); _meters.pop_back (); _widgets.pop_back (); old--; } if (old == sz) { return; } uint32_t c[10]; uint32_t b[4]; float stp[4]; c[0] = UIConfiguration::instance().color ("meter color0"); c[1] = UIConfiguration::instance().color ("meter color1"); c[2] = UIConfiguration::instance().color ("meter color2"); c[3] = UIConfiguration::instance().color ("meter color3"); c[4] = UIConfiguration::instance().color ("meter color4"); c[5] = UIConfiguration::instance().color ("meter color5"); c[6] = UIConfiguration::instance().color ("meter color6"); c[7] = UIConfiguration::instance().color ("meter color7"); c[8] = UIConfiguration::instance().color ("meter color8"); c[9] = UIConfiguration::instance().color ("meter color9"); b[0] = UIConfiguration::instance().color ("meter background bottom"); b[1] = UIConfiguration::instance().color ("meter background top"); b[2] = 0x991122ff; // red highlight gradient Bot b[3] = 0x551111ff; // red highlight gradient Top stp[0] = 115.0 * log_meter0dB (-18); stp[1] = 115.0 * log_meter0dB (-9); stp[2] = 115.0 * log_meter0dB (-3); stp[3] = 115.0; // XXX config changed -> update meter style (and size) for (size_t i = old; i < sz; ++i) { _meters.push_back (manage (new FastMeter (10 /* (uint32_t)floor (UIConfiguration::instance ().get_meter_hold ()) */, 8, FastMeter::Vertical, PX_SCALE (64), c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], b[0], b[1], b[2], b[3], stp[0], stp[1], stp[2], stp[3], (UIConfiguration::instance ().get_meter_style_led () ? 3 : 1)))); Gtk::VBox* vb = manage (new Gtk::VBox); char buf[16]; snprintf (buf, sizeof (buf), "%zu", i+1); Gtk::Label* l = manage (new Gtk::Label (buf)); vb->pack_start (*_meters.back(), true, true); vb->pack_start (*l, false, false, PX_SCALE(3)); _widgets.push_back (vb); _meter_box.pack_start (*vb, false, false, 0); } _meter_box.show_all (); if (get_parent ()) { queue_resize (); } } bool LiveTraxMeters::update_meters () { PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ()); size_t n = 0; for (auto const & p : aip) { if (n >= _meters.size()) { break; } _meters[n]->set (log_meter0dB (accurate_coefficient_to_dB (p.second.meter->level)), log_meter0dB (accurate_coefficient_to_dB (p.second.meter->peak))); ++n; } return true; }