From c44583ae7cc967e8072a8a9c8e52c6c655686aff Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 22 Mar 2024 18:57:59 -0600 Subject: [PATCH] working input meters, among other improvements for livetrax --- gtk2_ardour/ardour_ui.cc | 62 +++++++++++++- gtk2_ardour/ardour_ui.h | 6 +- gtk2_ardour/ardour_ui_dependents.cc | 23 ++++-- gtk2_ardour/ardour_ui_ed.cc | 9 ++- gtk2_ardour/livetrax_meters.cc | 116 +++++++++++++++++++++++++++ gtk2_ardour/livetrax_meters.h | 35 ++++++++ gtk2_ardour/session_option_editor.cc | 1 + gtk2_ardour/wscript | 1 + 8 files changed, 237 insertions(+), 16 deletions(-) create mode 100644 gtk2_ardour/livetrax_meters.cc create mode 100644 gtk2_ardour/livetrax_meters.h diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index d3f69de5fc..12a129838a 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1254,13 +1254,22 @@ ARDOUR_UI::set_fps_timeout_connection () void ARDOUR_UI::update_sample_rate () { - std::string label = string_compose (X_("%1:"), _("Audio")); + std::string label; + + if (!Profile->get_livetrax()) { + label = string_compose (X_("%1:"), _("Audio")); + } ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored) if (!AudioEngine::instance()->running()) { - sample_rate_label.set_markup (label + _("none")); + if (Profile->get_livetrax()) { + livetrax_sr_button->set_text (_("Stopped"), true); + } else { + const std::string str (label + _("none")); + sample_rate_label.set_markup (str); + } } else { @@ -1269,14 +1278,23 @@ ARDOUR_UI::update_sample_rate () if (rate == 0) { /* no sample rate available */ - sample_rate_label.set_markup (label + _("none")); + + if (Profile->get_livetrax()) { + livetrax_sr_button->set_text (_("Unknown"), true); + } else { + sample_rate_label.set_markup (label + _("none")); + } } else { char buf[64]; snprintf (buf, sizeof (buf), "%4.1f", (AudioEngine::instance()->usecs_per_cycle() / 1000.0f)); const char* const bg = (_session && _session->nominal_sample_rate () != rate) ? " background=\"red\" foreground=\"white\"" : ""; - sample_rate_label.set_markup (string_compose ("%1 %3 %4 %5", label, bg, ARDOUR_UI_UTILS::rate_as_string (rate), buf, _("ms"))); + const std::string str (string_compose ("%1 %3 %4 %5", label, bg, ARDOUR_UI_UTILS::rate_as_string (rate), buf, _("ms"))); + sample_rate_label.set_markup (str); + if (Profile->get_livetrax()) { + livetrax_sr_button->set_text (str, true); + } } } @@ -1341,6 +1359,42 @@ ARDOUR_UI::update_format () } format_label.set_markup (s.str ()); + + if (Profile->get_livetrax()) { + + s.str (""); + s.clear (); + + /* LiveTrax only allows a very limited set of options */ + + /* This looks like we could just unconditionally add "24bit" to + * the string, but this logic allows us to potentially detect + * logic glitches where somehow we end up with a different + * format. + */ + + switch (_session->config.get_native_file_data_format ()) { + case FormatInt24: + s << _("24bit"); + break; + default: + break; + } + + s << ' '; + + switch (_session->config.get_native_file_header_format ()) { + case RF64_WAV: + s << _("WAV/RF64"); + break; + case FLAC: + s << _("FLAC"); + default: + break; + } + + livetrax_sf_button->set_text (s.str(), false); + } } void diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 96041f8fc1..211ed83f9e 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -176,7 +176,7 @@ class NSM_Client; class LevelMeterHBox; class GUIObjectState; class BasicUI; -class MeterbridgeWidget; +class LiveTraxMeters; namespace ARDOUR { class ControlProtocolInfo; @@ -638,10 +638,12 @@ private: ArdourWidgets::ArdourButton* livetrax_mixer_view_button; ArdourWidgets::ArdourButton* livetrax_lock_button; ArdourWidgets::ArdourButton* livetrax_view_in_folder_button; + ArdourWidgets::ArdourButton* livetrax_sf_button; + ArdourWidgets::ArdourButton* livetrax_sr_button; Gtk::HScrollbar* livetrax_edit_hscrollbar; Gtk::VScrollbar* livetrax_edit_vscrollbar; Gtk::HScrollbar* livetrax_mix_hscrollbar; - Gtk::HBox livetrax_meter_box; + LiveTraxMeters* livetrax_meters; int livetrax_setup_windows (); /* menu bar and associated stuff */ diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index 1fa1d8c679..427f5f6e19 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -50,6 +50,7 @@ #include "meterbridge.h" #include "luainstance.h" #include "luawindow.h" +#include "livetrax_meters.h" #include "main_clock.h" #include "meterbridge.h" #include "mixer_ui.h" @@ -398,6 +399,7 @@ ARDOUR_UI::livetrax_setup_windows () Gtk::Label* l; Gtk::VBox* vb; Gtk::HBox* hb; + ArdourButton::Element elements (ArdourButton::Element (ArdourButton::Text|ArdourButton::VectorIcon)); livetrax_top_bar.set_spacing (12); livetrax_top_bar.set_border_width (12); @@ -412,8 +414,14 @@ ARDOUR_UI::livetrax_setup_windows () ev_dsp->add (dsp_load_label); ev_timecode->add (timecode_format_label); + livetrax_sr_button = manage (new ArdourButton ("")); + livetrax_sf_button = manage (new ArdourButton ("")); vb = manage (new Gtk::VBox); + vb->pack_start (*livetrax_sf_button, false, false); + vb->pack_start (*livetrax_sr_button, false, false); + livetrax_top_bar.pack_start (*vb, false, false); + vb = manage (new Gtk::VBox); vb->pack_start (*ev_dsp, true, true); vb->pack_start (disk_space_label, true, true); vb->show_all (); @@ -432,11 +440,9 @@ ARDOUR_UI::livetrax_setup_windows () /* transport bar */ - ArdourButton::Element elements (ArdourButton::Element (ArdourButton::Text|ArdourButton::VectorIcon)); - - livetrax_meter_view_button = manage (new ArdourButton (_("Meter Logo"), elements)); - livetrax_mixer_view_button = manage (new ArdourButton (_("Meter Logo"), elements)); - livetrax_editor_view_button = manage (new ArdourButton (_("Meter Logo"), elements)); + livetrax_meter_view_button = manage (new ArdourButton (_("Meter"), elements)); + livetrax_mixer_view_button = manage (new ArdourButton (_("Mixer"), elements)); + livetrax_editor_view_button = manage (new ArdourButton (_("Tracks"), elements)); livetrax_transport_bar.pack_start (*livetrax_editor_view_button, false, false); livetrax_transport_bar.pack_start (*livetrax_mixer_view_button, false, false); @@ -459,8 +465,10 @@ ARDOUR_UI::livetrax_setup_windows () /* meter display */ - l = manage (new Gtk::Label ("meter area")); - livetrax_meter_bar.pack_start (*l, true, true); + livetrax_meters = manage (new LiveTraxMeters (16)); + livetrax_meters->show_all (); + livetrax_meter_bar.set_border_width (12); + livetrax_meter_bar.pack_start (*livetrax_meters, true, true, 12); hb = manage (new Gtk::HBox); livetrax_edit_vscrollbar = manage (new Gtk::VScrollbar (editor->vertical_adjustment)); @@ -490,6 +498,7 @@ ARDOUR_UI::livetrax_setup_windows () connect_transport_elements (); setup_tooltips (); + build_menu_bar (); // setup_tooltips (); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 3c4d98651a..df4eaef001 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -810,15 +810,16 @@ ARDOUR_UI::build_menu_bar () if (!Profile->get_livetrax()) { ev_dsp->add (dsp_load_label); ev_timecode->add (timecode_format_label); + ev_audio->add (sample_rate_label); } ev_path->add (session_path_label); ev_name->add (snapshot_name_label); - ev_audio->add (sample_rate_label); ev_format->add (format_label); if (!Profile->get_livetrax()) { ev_dsp->show (); ev_timecode->show (); + ev_audio->show (); } ev_path->show (); ev_audio->show (); @@ -833,12 +834,14 @@ ARDOUR_UI::build_menu_bar () hbox->pack_end (error_alert_button, false, false, 2); hbox->pack_end (wall_clock_label, false, false, 10); - hbox->pack_end (*ev_dsp, false, false, 6); if (!Profile->get_livetrax()) { + hbox->pack_end (*ev_dsp, false, false, 6); hbox->pack_end (disk_space_label, false, false, 6); } hbox->pack_end (*ev_audio, false, false, 6); - hbox->pack_end (*ev_timecode, false, false, 6); + if (!Profile->get_livetrax()) { + hbox->pack_end (*ev_timecode, false, false, 6); + } hbox->pack_end (*ev_format, false, false, 6); hbox->pack_end (peak_thread_work_label, false, false, 6); hbox->pack_end (*ev_name, false, false, 6); diff --git a/gtk2_ardour/livetrax_meters.cc b/gtk2_ardour/livetrax_meters.cc new file mode 100644 index 0000000000..003dbd4f8c --- /dev/null +++ b/gtk2_ardour/livetrax_meters.cc @@ -0,0 +1,116 @@ +#include "ardour/logmeter.h" +#include "ardour/audioengine.h" + +#include "widgets/fastmeter.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 (size_t initial_cnt) +{ + set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_NEVER); + + resize (initial_cnt); + + meter_box.set_spacing (PX_SCALE (6)); + add (meter_box); + + fast_screen_update_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &LiveTraxMeters::update_meters), 40, GDK_PRIORITY_REDRAW + 10); +} + +LiveTraxMeters::~LiveTraxMeters () +{ + fast_screen_update_connection.disconnect (); +} + +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 (); + 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 (-15); + 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 ((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 (*l, false, false); + vb->pack_start (*meters.back(), true, true); + + widgets.push_back (vb); + + meter_box.pack_start (*vb, false, false, 0); + } + + meter_box.show_all (); +} + +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 (p.second.meter->level, p.second.meter->peak); + ++n; + } + + return true; +} diff --git a/gtk2_ardour/livetrax_meters.h b/gtk2_ardour/livetrax_meters.h new file mode 100644 index 0000000000..247f2e5195 --- /dev/null +++ b/gtk2_ardour/livetrax_meters.h @@ -0,0 +1,35 @@ +#ifndef __ardour_gtk_livetrax_meters_h__ +#define __ardour_gtk_livetrax_meters_h__ + +#include + +#include +#include + +namespace Gtk { + class Label; +} + +namespace ArdourWidgets { + class FastMeter; +} + +class LiveTraxMeters : public Gtk::ScrolledWindow +{ + public: + LiveTraxMeters (size_t initial_cnt); + ~LiveTraxMeters (); + + void resize (size_t); + + private: + Gtk::HBox meter_box; + Gtk::HBox global_hbox; + std::vector widgets; + std::vector meters; + sigc::connection fast_screen_update_connection; + + bool update_meters (); +}; + +#endif /* __ardour_gtk_livetrax_meters_h__ */ diff --git a/gtk2_ardour/session_option_editor.cc b/gtk2_ardour/session_option_editor.cc index 42dcb88398..fd74c23816 100644 --- a/gtk2_ardour/session_option_editor.cc +++ b/gtk2_ardour/session_option_editor.cc @@ -497,6 +497,7 @@ SessionOptionEditor::parameter_changed (std::string const & p) _sf->add (FormatInt24, _("24-bit integer")); _sf->add (FormatInt16, _("16-bit integer")); } + if (need_refill) { parameter_changed ("native-file-data-format"); } diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index d1e0f94274..2165a19c8c 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -143,6 +143,7 @@ gtk2_ardour_sources = [ 'led.cc', 'level_meter.cc', 'library_download_dialog.cc', + 'livetrax_meters.cc', 'location_ui.cc', 'loudness_dialog.cc', 'loudness_settings.cc',