diff --git a/gtk2_ardour/loudness_dialog.cc b/gtk2_ardour/loudness_dialog.cc
index 6b8793c3a3..1e74e8565a 100644
--- a/gtk2_ardour/loudness_dialog.cc
+++ b/gtk2_ardour/loudness_dialog.cc
@@ -23,8 +23,8 @@
#include "pbd/unwind.h"
#include "ardour/dB.h"
-#include "ardour/plugin_manager.h"
#include "ardour/plugin_insert.h"
+#include "ardour/plugin_manager.h"
#include "ardour/processor.h"
#include "ardour/session.h"
@@ -40,9 +40,11 @@
#include "gtkmm2ext/utils.h"
#include "widgets/ardour_spacer.h"
+#include "widgets/prompter.h"
#include "widgets/tooltips.h"
#include "ardour_message.h"
+#include "export_analysis_graphs.h"
#include "export_report.h"
#include "loudness_dialog.h"
#include "ui_config.h"
@@ -53,39 +55,19 @@ using namespace Gtk;
using namespace ARDOUR;
using namespace ArdourWidgets;
-/* https://www.masteringthemix.com/blogs/learn/76296773-mastering-audio-for-soundcloud-itunes-spotify-and-youtube
- * https://youlean.co/loudness-standards-full-comparison-table/
- */
-LoudnessDialog::LoudnessPreset LoudnessDialog::presets[] =
-{
- /* | dbFS dBTP LUFS short mom. | FS, TP , int, sht, mom |maxIntg| notes */
- {"-Analysis Only-", { false, false, false, false, false}, { 0, 0.0, 0, 0, 0 }, { 0.0, -200.0}},
- {"EBU R128", { false, true, true, false, false}, { 0, -1.0, -23, 0, 0 }, {-22.5, -23.5}}, // +/- 0.5 LU
- {"EBU R128 S1", { false, true, true, true, false}, { 0, -1.0, -23, -18, 0 }, {-22.5, -23.5}}, // +/- 0.5 LU
- {"ATSC A/85", { false, true, true, true, false}, { 0, -2.0, -24, 0, 0 }, {-22.0, -26.0}}, // +/- 2 LU
- {"AES Streaming", { false, true, true, false, false}, { 0, -1.0, -18, 0, 0 }, {-16.0, -20.0}}, // min/max Integrated: -20 / -16 LUFS - same as "ASWG-R001 PORTABLE"
- {"ASWG-R001 HOME", { false, true, true, true, false}, { 0, -1.0, -24, 0, 0 }, {-22.0, -26.0}}, // +/- 2 LU
- {"Digital Peak", { true, false, false, false, false}, { 0, 0.0, 0, 0, 0 }, { 0.0, -200.0}},
- {"CD", { true, true, true, false, false}, { 0, -0.1, -9, 0, 0 }, { 0.0, -200.0}},
-
- {"Amazon Music", { false, true, true, false, false}, { 0, -2.0, -14, 0, 0 }, { -9.0, -19.0}}, // -9 to -19 LUFS
- {"Apple Music", { false, true, true, false, false}, { 0, -1.0, -16, 0, 0 }, {-15.0, -17.0}}, // (+/- 1.0 LU)
- {"Deezer", { false, true, true, false, false}, { 0, -1.0, -15, 0, 0 }, {-14.0, -16.0}}, // -14 to -16 LUFS
- {"Soundcloud", { false, true, true, false, false}, { 0, -1.0, -10, 0, 0 }, { -8.0, -13.0}}, // -8 to -13 LUFS
- {"Spotify", { false, true, true, false, false}, { 0, -1.0, -14, 0, 0 }, { -8.0, -20.0}}, // Spotify use replay-gain to match -14 or -11 ..
- {"Spotify Loud", { false, true, true, false, false}, { 0, -2.0, -11, 0, 0 }, { -5.0, -17.0}}, // .. so the min/max range is arbitrary +/- 6dB
- {"Youtube", { false, true, true, false, false}, { 0, -1.0, -14, 0, 0 }, {-13.0, -15.0}}, // -13 to -15 LUFS
-};
-
-LoudnessDialog::LoudnessPreset LoudnessDialog::_preset = LoudnessDialog::presets [1];
+bool LoudnessDialog::_first_time = true;
+CLoudnessPreset LoudnessDialog::_last_preset;
LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
: ArdourDialog (as ? _("Loudness Assistant") : _("Loudness Analyzer and Normalizer"))
+ , _lp (false)
, _session (s)
, _range (ar)
, _status (s->get_export_status ())
, _autostart (as)
- , _conformity_expander (_("Conformity Analysis (with gain applied)"))
+ , _conformity_frame (_("Conformity Analysis (with gain applied)"))
+ , _save_preset (_("Save"))
+ , _remove_preset (_("Remove"))
, _dbfs_btn (_("Peak:"), ArdourButton::led_default_elements, true)
, _dbtp_btn (_("True Peak:"), ArdourButton::led_default_elements, true)
, _lufs_i_btn (_("Integrated Loudness:"), ArdourButton::led_default_elements, true)
@@ -93,13 +75,13 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
, _lufs_m_btn (_("Max. Momentary Loudness:"), ArdourButton::led_default_elements, true)
, _rt_analysis_button (_("Realtime"), ArdourButton::led_default_elements, true)
, _start_analysis_button (_("Analyze"))
- , _show_report_button (_("Show Graphical Analysis"))
+ , _show_report_button (_("Analysis Report"))
, _custom_pos_button (_("Custom Amplifier Position"), ArdourButton::led_default_elements, true)
- , _dbfs_adjustment ( 0.00, -90.00, 0.00, 0.1, 0.2)
- , _dbtp_adjustment ( -1.0, -90.00, 0.00, 0.1, 0.2)
- , _lufs_i_adjustment (-23.0, -90.00, 0.00, 0.1, 1.0)
- , _lufs_s_adjustment (-20.0, -90.00, 0.00, 0.1, 1.0)
- , _lufs_m_adjustment (-17.0, -90.00, 0.00, 0.1, 1.0)
+ , _dbfs_adjustment (0.00, -10.00, 0.00, 0.1, 0.2)
+ , _dbtp_adjustment (-1.0, -10.00, 0.00, 0.1, 0.2)
+ , _lufs_i_adjustment (-23.0, -90.00, 0.00, 0.5, 1.0)
+ , _lufs_s_adjustment (-20.0, -90.00, 0.00, 0.5, 1.0)
+ , _lufs_m_adjustment (-17.0, -90.00, 0.00, 0.5, 1.0)
, _dbfs_spinbutton (_dbfs_adjustment, 0.1, 1)
, _dbtp_spinbutton (_dbtp_adjustment, 0.1, 1)
, _lufs_i_spinbutton (_lufs_i_adjustment, 0.1, 1)
@@ -110,11 +92,19 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
, _ignore_preset (false)
, _ignore_change (false)
{
+ _preset = _lp[0];
+ if (_first_time) {
+ _first_time = false;
+ _last_preset = _lp[0];
+ }
+
+ _preset = _last_preset;
+
/* Dialog can be displayed from the mixer, override global transient_parent */
unset_transient_for ();
/* query initial gain */
- _gain_out = accurate_coefficient_to_dB (_session->master_volume()->get_value());
+ _gain_out = accurate_coefficient_to_dB (_session->master_volume ()->get_value ());
/* setup styles */
_start_analysis_button.set_name ("generic button");
@@ -128,6 +118,9 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
_start_analysis_button.set_size_request (-1, req.height * 1.1);
_rt_analysis_button.set_size_request (-1, req.height * 1.1);
+ _save_preset.set_name ("generic button");
+ _remove_preset.set_name ("generic button");
+
_dbfs_btn.set_name ("generic button");
_dbtp_btn.set_name ("generic button");
_lufs_i_btn.set_name ("generic button");
@@ -140,105 +133,117 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
_lufs_s_btn.set_led_left (true);
_lufs_m_btn.set_led_left (true);
+ _preset_dropdown.set_can_focus (true);
_start_analysis_button.set_can_focus (true);
_rt_analysis_button.set_can_focus (true);
_show_report_button.set_can_focus (true);
_custom_pos_button.set_can_focus (true);
+ _save_preset.set_can_focus (true);
+ _remove_preset.set_can_focus (true);
_dbfs_btn.set_can_focus (true);
_dbtp_btn.set_can_focus (true);
_lufs_i_btn.set_can_focus (true);
_lufs_s_btn.set_can_focus (true);
_lufs_m_btn.set_can_focus (true);
- _dbfs_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _dbtp_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _lufs_i_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _lufs_s_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _lufs_m_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
+ _dbfs_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _dbtp_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _lufs_i_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _lufs_s_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _lufs_m_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
- _delta_dbfs_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _delta_dbtp_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _delta_lufs_i_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _delta_lufs_s_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _delta_lufs_m_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
+ _delta_dbfs_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _delta_dbtp_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _delta_lufs_i_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _delta_lufs_s_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _delta_lufs_m_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
- _gain_out_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _gain_norm_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _gain_total_label.modify_font (UIConfiguration::instance().get_NormalMonospaceFont());
- _gain_exceeds_label.modify_font (UIConfiguration::instance().get_NormalFont());
+ _gain_out_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _gain_norm_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _gain_total_label.modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
+ _gain_exceeds_label.modify_font (UIConfiguration::instance ().get_NormalFont ());
/* result display layout */
-#define ROW row, row +1
+#define ROW row, row + 1
- int row;
+ int row = 0;
Label* l;
- Table* t = manage (new Table (12, 4, false));
+ Table* t = manage (new Table (11, 8, false));
t->set_spacings (4);
- l = manage (new Label (_("Analysis Results"), ALIGN_LEFT));
- l->set_use_markup (true);
- t->attach (*l, 0, 1, 0, 1);
l = manage (new Label (_("Preset:"), ALIGN_LEFT));
- t->attach (*l, 0, 1, 1, 2);
+ t->attach (*l, 0, 1, ROW, SHRINK | FILL);
+ t->attach (_preset_dropdown, 1, 3, ROW);
- t->attach (_show_report_button, 1, 4, 0, 1);
- t->attach (_preset_dropdown, 1, 3, 1, 2);
+ t->attach (_save_preset, 3, 4, ROW, SHRINK | FILL);
+ t->attach (_remove_preset, 4, 5, ROW, SHRINK | FILL);
+ /* horiz space */
+ l = manage (new Label (" ", ALIGN_LEFT));
+ t->attach (*l, 5, 6, ROW, SHRINK, SHRINK, 6, 0);
+
+ l = manage (new Label (" ", ALIGN_LEFT));
+ t->attach (*l, 6, 7, ROW);
+
+ t->attach (_show_report_button, 7, 8, ROW, SHRINK | FILL);
+
+ ++row;
l = manage (new Label (_("Target"), ALIGN_CENTER));
l->set_use_markup (true);
- t->attach (*l, 1, 2, 2, 3);
+ t->attach (*l, 2, 3, ROW);
l = manage (new Label (_("Measured"), ALIGN_CENTER));
l->set_use_markup (true);
- t->attach (*l, 2, 3, 2, 3);
+ t->attach (*l, 3, 4, ROW);
l = manage (new Label (_("Delta"), ALIGN_CENTER));
l->set_use_markup (true);
- t->attach (*l, 3, 4, 2, 3);
+ t->attach (*l, 4, 5, ROW);
- row = 3;
- t->attach (_dbfs_btn, 0, 1, ROW); ++row;
- t->attach (_dbtp_btn, 0, 1, ROW); ++row;
- t->attach (_lufs_i_btn, 0, 1, ROW); ++row;
- t->attach (_lufs_s_btn, 0, 1, ROW); ++row;
- t->attach (_lufs_m_btn, 0, 1, ROW); ++row;
+ row = 2;
+ t->attach (_dbfs_btn, 0, 2, ROW); ++row;
+ t->attach (_dbtp_btn, 0, 2, ROW); ++row;
+ t->attach (_lufs_i_btn, 0, 2, ROW); ++row;
+ t->attach (_lufs_s_btn, 0, 2, ROW); ++row;
+ t->attach (_lufs_m_btn, 0, 2, ROW); ++row;
++row; // spacer
l = manage (new Label (_("Gain to normalize:"), ALIGN_LEFT));
- t->attach (*l, 0, 1, ROW); ++row;
+ t->attach (*l, 0, 2, ROW); ++row;
l = manage (new Label (_("Previous output gain:"), ALIGN_LEFT));
- t->attach (*l, 0, 1, ROW); ++row;
+ t->attach (*l, 0, 2, ROW); ++row;
l = manage (new Label (_("Total gain:"), ALIGN_LEFT));
- t->attach (*l, 0, 1, ROW); ++row;
+ t->attach (*l, 0, 2, ROW);
- row = 3;
- t->attach (_dbfs_spinbutton, 1, 2, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
- t->attach (_dbtp_spinbutton, 1, 2, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
- t->attach (_lufs_i_spinbutton, 1, 2, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
- t->attach (_lufs_s_spinbutton, 1, 2, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
- t->attach (_lufs_m_spinbutton, 1, 2, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
+ row = 2;
+ t->attach (_dbfs_spinbutton, 2, 3, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
+ t->attach (_dbtp_spinbutton, 2, 3, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
+ t->attach (_lufs_i_spinbutton, 2, 3, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
+ t->attach (_lufs_s_spinbutton, 2, 3, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
+ t->attach (_lufs_m_spinbutton, 2, 3, ROW, EXPAND|FILL, EXPAND|FILL, 8, 0); ++row;
- row = 3;
- t->attach (_dbfs_label, 2, 3, ROW); ++row;
- t->attach (_dbtp_label, 2, 3, ROW); ++row;
- t->attach (_lufs_i_label, 2, 3, ROW); ++row;
- t->attach (_lufs_s_label, 2, 3, ROW); ++row;
- t->attach (_lufs_m_label, 2, 3, ROW); ++row;
+ row = 2;
+ t->attach (_dbfs_label, 3, 4, ROW); ++row;
+ t->attach (_dbtp_label, 3, 4, ROW); ++row;
+ t->attach (_lufs_i_label, 3, 4, ROW); ++row;
+ t->attach (_lufs_s_label, 3, 4, ROW); ++row;
+ t->attach (_lufs_m_label, 3, 4, ROW); ++row;
- row = 3;
- t->attach (_delta_dbfs_label, 3, 4, ROW); ++row;
- t->attach (_delta_dbtp_label, 3, 4, ROW); ++row;
- t->attach (_delta_lufs_i_label, 3, 4, ROW); ++row;
- t->attach (_delta_lufs_s_label, 3, 4, ROW); ++row;
- t->attach (_delta_lufs_m_label, 3, 4, ROW); ++row;
+ row = 2;
+ t->attach (_delta_dbfs_label, 4, 5, ROW); ++row;
+ t->attach (_delta_dbtp_label, 4, 5, ROW); ++row;
+ t->attach (_delta_lufs_i_label, 4, 5, ROW); ++row;
+ t->attach (_delta_lufs_s_label, 4, 5, ROW); ++row;
+ t->attach (_delta_lufs_m_label, 4, 5, ROW); ++row;
ArdourHSpacer* spc = manage (new ArdourHSpacer (1.0));
- t->attach (*spc, 2, 4, ROW); ++row;
- t->attach (_gain_norm_label, 3, 4, ROW); ++row;
- t->attach (_gain_out_label, 3, 4, ROW); ++row;
- t->attach (_gain_exceeds_label, 2, 3, ROW);
- t->attach (_gain_total_label, 3, 4, ROW); ++row;
- t->attach (_custom_pos_button, 1, 4, ROW); ++row;
+ t->attach (*spc, 3, 5, ROW); ++row;
+ t->attach (_gain_norm_label, 4, 5, ROW); ++row;
+ t->attach (_gain_out_label, 4, 5, ROW); ++row;
+ t->attach (_gain_exceeds_label, 3, 4, ROW);
+ t->attach (_gain_total_label, 4, 5, ROW);
+ t->attach (_custom_pos_button, 7, 8, row - 1, row + 1, SHRINK | FILL, SHRINK);
+ t->attach (_conformity_frame, 6, 8, 1, row - 3, SHRINK | FILL, EXPAND | FILL, 0, 0);
set_tooltip (_custom_pos_button,
_("When enabled an amplifier processor is used to apply the gain. "
@@ -265,8 +270,11 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
_gain_total_label.set_alignment (ALIGN_RIGHT);
_gain_exceeds_label.set_alignment (ALIGN_RIGHT);
+ HBox* hb = manage (new (HBox));
+ hb->pack_start (_loudness_graph, true, false);
+
+ _result_box.pack_start (*hb, false, false, 0);
_result_box.pack_start (*t, false, false, 6);
- _result_box.pack_start (_conformity_expander, false, false, 6);
/* analysis progress layout */
_progress_box.pack_start (_progress_bar, false, false, 6);
@@ -277,27 +285,25 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
l = manage (new Label ());
l->set_markup (_("Loudness Analysis\n"));
l->set_alignment (ALIGN_LEFT, ALIGN_TOP);
- t->attach (*l, 0, 1, 0, 1, EXPAND|FILL, FILL, 8, 2);
+ t->attach (*l, 0, 1, 0, 1, EXPAND | FILL, FILL, 8, 2);
l = manage (new Label ());
l->set_line_wrap ();
l->set_alignment (ALIGN_LEFT, ALIGN_TOP);
l->set_markup (_(
- "This allows the user to analyze and conform the loudness of the signal at the master-bus "
- "output of the complete session, as it would be exported. "
- "When using this feature, remember to disable normalization in the session export profile."
- ));
- t->attach (*l, 0, 1, 1, 2, EXPAND|FILL, FILL, 8, 2);
+ "This allows the user to analyze and conform the loudness of the signal at the master-bus "
+ "output of the complete session, as it would be exported. "
+ "When using this feature, remember to disable normalization in the session export profile."));
+ t->attach (*l, 0, 1, 1, 2, EXPAND | FILL, FILL, 8, 2);
l = manage (new Label ());
l->set_line_wrap ();
l->set_alignment (ALIGN_LEFT, ALIGN_TOP);
l->set_markup (_(
- "By default, a faster-than-realtime export is used to assess the loudness of the "
- "session. If any outboard gear is used, a realtime export is available, to "
- "play at normal speed."
- ));
- t->attach (*l, 0, 1, 2, 3, EXPAND|FILL, FILL, 8, 2);
+ "By default, a faster-than-realtime export is used to assess the loudness of the "
+ "session. If any outboard gear is used, a realtime export is available, to "
+ "play at normal speed."));
+ t->attach (*l, 0, 1, 2, 3, EXPAND | FILL, FILL, 8, 2);
Alignment* align = manage (new Alignment (0, 0, 1, 0));
align->add (_start_analysis_button);
@@ -310,39 +316,44 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
_setup_box.pack_start (*t, false, false, 6);
/* global layout */
- get_vbox()->pack_start (_setup_box);
- get_vbox()->pack_start (_progress_box);
- get_vbox()->pack_start (_result_box);
+ get_vbox ()->pack_start (_setup_box);
+ get_vbox ()->pack_start (_progress_box);
+ get_vbox ()->pack_start (_result_box);
- _progress_box.set_size_request (400,-1);
+ _progress_box.set_size_request (400, -1);
_ok_button = add_button (Stock::APPLY, RESPONSE_APPLY);
_cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
/* fill in presets */
- for (size_t i = 0; i < sizeof (presets) / sizeof (LoudnessDialog::LoudnessPreset); ++i) {
+ for (size_t i = 0; i < _lp.n_presets (); ++i) {
using namespace Gtkmm2ext;
- _preset_dropdown.AddMenuElem (MenuElemNoMnemonic (presets[i].name, sigc::bind (sigc::mem_fun (*this, &LoudnessDialog::load_preset), i)));
+ _preset_dropdown.AddMenuElem (MenuElemNoMnemonic (_lp[i].label, sigc::bind (sigc::mem_fun (*this, &LoudnessDialog::load_preset), i)));
}
- _initial_preset_name = _preset.name;
- if (_preset.name != _("Custom")) {
- /* call _menu.set_active to initialize 'current_active' item */
- PBD::Unwinder uw (_ignore_preset, true);
- _preset_dropdown.set_active (_preset.name);
- }
apply_preset ();
- _conformity_expander.set_expanded(false);
+ if (!_lp.find_preset (_preset)) {
+ _preset.label = _("Custom");
+ }
+
+ check_preset ();
+
_gain_out_label.set_text (string_compose (_("%1 dB"), std::setprecision (2), std::showpos, std::fixed, _gain_out));
+ /* setup graph */
+ _loudness_graph.signal_size_request ().connect (sigc::mem_fun (*this, &LoudnessDialog::graph_size_request));
+ _loudness_graph.signal_expose_event ().connect (sigc::mem_fun (*this, &LoudnessDialog::graph_expose_event));
+
/* connect signals */
- _cancel_button->signal_clicked().connect (sigc::mem_fun (this, &LoudnessDialog::cancel_analysis));
- _dbfs_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::update_settings));
- _dbtp_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::update_settings));
- _lufs_i_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::update_settings));
- _lufs_s_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::update_settings));
- _lufs_m_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _cancel_button->signal_clicked ().connect (sigc::mem_fun (this, &LoudnessDialog::cancel_analysis));
+ _dbfs_spinbutton.signal_value_changed ().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _dbtp_spinbutton.signal_value_changed ().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _lufs_i_spinbutton.signal_value_changed ().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _lufs_s_spinbutton.signal_value_changed ().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _lufs_m_spinbutton.signal_value_changed ().connect (mem_fun (*this, &LoudnessDialog::update_settings));
+ _save_preset.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::save_preset));
+ _remove_preset.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::remove_preset));
_show_report_button.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::display_report));
_start_analysis_button.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::start_analysis));
_dbfs_btn.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::update_settings));
@@ -350,7 +361,6 @@ LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
_lufs_i_btn.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::update_settings));
_lufs_s_btn.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::update_settings));
_lufs_m_btn.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::update_settings));
- _conformity_expander.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &LoudnessDialog::toggle_conformity_display));
_ok_button->set_sensitive (false);
_show_report_button.set_sensitive (false);
@@ -365,7 +375,7 @@ void
LoudnessDialog::cancel_analysis ()
{
if (_status->running ()) {
- _status->abort();
+ _status->abort ();
}
}
@@ -405,19 +415,7 @@ LoudnessDialog::run ()
_session->master_volume ()->set_value (dB_to_coefficient (gain_db ()), PBD::Controllable::NoGroup);
_session->master_out()->set_volume_applies_to_output (!_custom_pos_button.get_active ());
- _preset.level[0] = _dbfs_spinbutton.get_value();
- _preset.level[1] = _dbtp_spinbutton.get_value();
- _preset.level[2] = _lufs_i_spinbutton.get_value();
- _preset.level[3] = _lufs_s_spinbutton.get_value();
- _preset.level[4] = _lufs_m_spinbutton.get_value();
- _preset.enable[0] = _dbfs_btn.get_active ();
- _preset.enable[1] = _dbtp_btn.get_active ();
- _preset.enable[2] = _lufs_i_btn.get_active ();
- _preset.enable[3] = _lufs_s_btn.get_active ();
- _preset.enable[4] = _lufs_m_btn.get_active ();
- } else {
- /* retore preset name, in case user has changed it */
- _preset.name = _initial_preset_name;
+ _last_preset = _preset;
}
return r;
@@ -426,7 +424,7 @@ LoudnessDialog::run ()
gint
LoudnessDialog::progress_timeout ()
{
- float progress = ((float) _status->processed_samples_current_timespan) / _status->total_samples_current_timespan;
+ float progress = ((float)_status->processed_samples_current_timespan) / _status->total_samples_current_timespan;
_progress_bar.set_text ("Analyzing");
_progress_bar.set_fraction (progress);
return true;
@@ -435,18 +433,19 @@ LoudnessDialog::progress_timeout ()
int
LoudnessDialog::analyze ()
{
- /* These are ensured in Editor::measure_master_loudness () */
- assert (_session->master_out());
+ /* These are ensured in Editor::measure_master_loudness () */
+ assert (_session->master_out ());
assert (_session->master_volume ());
- assert (_session->master_out()->output());
- assert (_session->master_out()->output()->n_ports().n_audio() == 2);
+ assert (_session->master_out ()->output ());
+ assert (_session->master_out ()->output ()->n_ports ().n_audio () == 2);
assert (_range.start < _range.end);
- ExportTimespanPtr tsp = _session->get_export_handler()->add_timespan();
- boost::shared_ptr ccp = _session->get_export_handler()->add_channel_config();
- boost::shared_ptr fnp = _session->get_export_handler()->add_filename();
- boost::shared_ptr fmp = _session->get_export_handler()->add_format();
+ ExportTimespanPtr tsp = _session->get_export_handler ()->add_timespan ();
+
+ boost::shared_ptr ccp = _session->get_export_handler ()->add_channel_config ();
+ boost::shared_ptr fnp = _session->get_export_handler ()->add_filename ();
+ boost::shared_ptr fmp = _session->get_export_handler ()->add_format ();
/* setup format */
fmp->set_tag (false);
@@ -465,9 +464,9 @@ LoudnessDialog::analyze ()
tsp->set_name ("master");
/* setup channels, use master out */
- IO* master_out = _session->master_out()->output().get();
- for (uint32_t n = 0; n < master_out->n_ports().n_audio(); ++n) {
- PortExportChannel * channel = new PortExportChannel ();
+ IO* master_out = _session->master_out ()->output ().get ();
+ for (uint32_t n = 0; n < master_out->n_ports ().n_audio (); ++n) {
+ PortExportChannel* channel = new PortExportChannel ();
channel->add_port (master_out->audio (n));
ExportChannelPtr chan_ptr (channel);
ccp->register_channel (chan_ptr);
@@ -475,9 +474,9 @@ LoudnessDialog::analyze ()
/* do audio export */
boost::shared_ptr b;
- _session->get_export_handler()->reset ();
- _session->get_export_handler()->add_export_config (tsp, ccp, fmp, fnp, b);
- _session->get_export_handler()->do_export();
+ _session->get_export_handler ()->reset ();
+ _session->get_export_handler ()->add_export_config (tsp, ccp, fmp, fnp, b);
+ _session->get_export_handler ()->do_export ();
/* show progress */
_setup_box.hide ();
@@ -488,27 +487,27 @@ LoudnessDialog::analyze ()
get_size (wr.width, wr.height);
resize (wr.width, 60);
- sigc::connection progress_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &LoudnessDialog::progress_timeout), 100);
+ sigc::connection progress_connection = Glib::signal_timeout ().connect (sigc::mem_fun (*this, &LoudnessDialog::progress_timeout), 100);
while (_status->running ()) {
- if (gtk_events_pending()) {
+ if (gtk_events_pending ()) {
gtk_main_iteration ();
} else {
Glib::usleep (10000);
}
}
- progress_connection.disconnect();
+ progress_connection.disconnect ();
_progress_box.hide_all ();
/* done */
- _status->finish (TRS_UI);
+ _status->finish (TRS_UI);
- if (!_status->aborted() && _status->result_map.size () != 1) {
+ if (!_status->aborted () && _status->result_map.size () != 1) {
ArdourMessageDialog (_("Loudness measurement returned no results. Likely because the analyzed range is to short."), false, MESSAGE_ERROR).run ();
return 1;
}
- return _status->aborted() ? 1 : 0;
+ return _status->aborted () ? 1 : 0;
}
void
@@ -516,7 +515,79 @@ LoudnessDialog::display_report ()
{
ExportReport er (_("Export Loudness Report"), _status->result_map);
er.set_transient_for (*this);
- er.run();
+ er.run ();
+}
+
+void
+LoudnessDialog::save_preset ()
+{
+ assert (_preset.user);
+ ArdourWidgets::Prompter name_prompter (*this, true, true);
+ name_prompter.set_title (_("Save Loudness Preset"));
+ name_prompter.set_prompt (_("Name:"));
+ name_prompter.add_button (_("Save"), Gtk::RESPONSE_ACCEPT);
+ name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+ name_prompter.set_initial_text (_preset.label, _preset.label != _("Custom"));
+ name_prompter.show_all ();
+
+ bool saved = false;
+ bool done = false;
+ std::string result;
+
+ while (!done) {
+ switch (name_prompter.run ()) {
+ case Gtk::RESPONSE_ACCEPT:
+ name_prompter.get_result (result);
+ name_prompter.hide ();
+ if (result.length()) {
+ if (result == _("Custom")) {
+ /* ask again */
+ continue;
+ }
+ _preset.label = result;
+ _preset.report = false;
+ if (_lp.push_back (_preset)) {
+ done = true;
+ saved = true;
+ } else {
+ /* Invalid Name, ask again */
+ }
+ } else {
+ /* nothing entered, just get out of here */
+ done = true;
+ }
+ break;
+ default:
+ done = true;
+ break;
+ }
+ }
+ if (saved) {
+ _preset_dropdown.clear_items ();
+ for (size_t i = 0; i < _lp.n_presets (); ++i) {
+ using namespace Gtkmm2ext;
+ _preset_dropdown.AddMenuElem (MenuElemNoMnemonic (_lp[i].label, sigc::bind (sigc::mem_fun (*this, &LoudnessDialog::load_preset), i)));
+ }
+ PBD::Unwinder uw (_ignore_preset, true);
+ _preset_dropdown.set_active (_preset.label);
+ _save_preset.set_sensitive (false);
+ _remove_preset.set_sensitive (_preset.user);
+ }
+}
+
+void
+LoudnessDialog::remove_preset ()
+{
+ assert (_preset.user);
+ if (_lp.erase (_preset)) {
+ _preset_dropdown.clear_items ();
+ for (size_t i = 0; i < _lp.n_presets (); ++i) {
+ using namespace Gtkmm2ext;
+ _preset_dropdown.AddMenuElem (MenuElemNoMnemonic (_lp[i].label, sigc::bind (sigc::mem_fun (*this, &LoudnessDialog::load_preset), i)));
+ }
+ _preset.label = _("Custom");
+ update_settings ();
+ }
}
void
@@ -525,7 +596,9 @@ LoudnessDialog::load_preset (size_t n)
if (_ignore_preset) {
return;
}
- _preset = presets[n];
+ _preset = _lp[n];
+ _save_preset.set_sensitive (false);
+ _remove_preset.set_sensitive (_preset.user);
apply_preset ();
calculate_gain ();
}
@@ -534,7 +607,7 @@ void
LoudnessDialog::apply_preset ()
{
PBD::Unwinder uw (_ignore_change, true);
- _preset_dropdown.set_text (_preset.name);
+ _preset_dropdown.set_text (_preset.label);
_dbfs_btn.set_active (_preset.enable[0]);
_dbtp_btn.set_active (_preset.enable[1]);
@@ -559,15 +632,44 @@ LoudnessDialog::update_sensitivity ()
_lufs_m_spinbutton.set_sensitive (_lufs_m_btn.get_active () && _lufs_m_btn.sensitive ());
}
+void
+LoudnessDialog::check_preset ()
+{
+ if (_lp.find_preset (_preset)) {
+ _save_preset.set_sensitive (false);
+ _remove_preset.set_sensitive (_preset.user);
+ } else {
+ if (!_preset.user) {
+ _preset.label = _("Custom");
+ }
+ _preset.user = true;
+ _preset.report = false;
+ _save_preset.set_sensitive (true);
+ _remove_preset.set_sensitive (false);
+ }
+ _preset_dropdown.set_text (_preset.label);
+}
+
void
LoudnessDialog::update_settings ()
{
if (_ignore_change) {
return;
}
- _preset.name = _("Custom");
- _preset_dropdown.set_text (_preset.name);
+ /* check if preset with current settings exists */
+ _preset.level[0] = _dbfs_spinbutton.get_value ();
+ _preset.level[1] = _dbtp_spinbutton.get_value ();
+ _preset.level[2] = _lufs_i_spinbutton.get_value ();
+ _preset.level[3] = _lufs_s_spinbutton.get_value ();
+ _preset.level[4] = _lufs_m_spinbutton.get_value ();
+ _preset.enable[0] = _dbfs_btn.get_active ();
+ _preset.enable[1] = _dbtp_btn.get_active ();
+ _preset.enable[2] = _lufs_i_btn.get_active ();
+ _preset.enable[3] = _lufs_s_btn.get_active ();
+ _preset.enable[4] = _lufs_m_btn.get_active ();
+
+ check_preset ();
update_sensitivity ();
calculate_gain ();
}
@@ -583,19 +685,22 @@ LoudnessDialog::display_results ()
{
AnalysisResults const& ar (_status->result_map);
assert (ar.size () == 1);
- ExportAnalysisPtr p = ar.begin()->second;
+ ExportAnalysisPtr p = ar.begin ()->second;
- if (!p->have_loudness || !p->have_dbtp) {
+ if (!p->have_loudness || !p->have_dbtp || !p->have_lufs_graph) {
ArdourMessageDialog (
- string_compose (_("True-peak and loudness measurement failed. %1-VAMP analysis plugin is missing on your system. Please contact your vendor."), PROGRAM_NAME),
- false, MESSAGE_ERROR).run ();
+ string_compose (_("True-peak and loudness measurement failed. %1-VAMP analysis plugin is missing on your system. Please contact your vendor."), PROGRAM_NAME),
+ false, MESSAGE_ERROR)
+ .run ();
}
+ plot_graph (p);
+
_dbfs = accurate_coefficient_to_dB (p->peak);
_dbtp = accurate_coefficient_to_dB (p->truepeak);
- _lufs_i = p->integrated_loudness > -200 ? p->integrated_loudness : -std::numeric_limits::infinity();
- _lufs_s = p->max_loudness_short > -200 ? p->max_loudness_short : -std::numeric_limits::infinity();
- _lufs_m = p->max_loudness_momentary > - 200 ? p->max_loudness_momentary : -std::numeric_limits::infinity();
+ _lufs_i = p->integrated_loudness > -200 ? p->integrated_loudness : -std::numeric_limits::infinity ();
+ _lufs_s = p->max_loudness_short > -200 ? p->max_loudness_short : -std::numeric_limits::infinity ();
+ _lufs_m = p->max_loudness_momentary > -200 ? p->max_loudness_momentary : -std::numeric_limits::infinity ();
_dbfs_btn.set_sensitive (_dbfs > -300);
_dbtp_btn.set_sensitive (_dbtp > -300);
@@ -619,17 +724,24 @@ LoudnessDialog::display_results ()
void
LoudnessDialog::calculate_gain ()
{
- float dbfs = _dbfs_spinbutton.get_value();
- float dbtp = _dbtp_spinbutton.get_value();
- float lufs_i = _lufs_i_spinbutton.get_value();
- float lufs_s = _lufs_s_spinbutton.get_value();
- float lufs_m = _lufs_m_spinbutton.get_value();
+ float dbfs = _dbfs_spinbutton.get_value ();
+ float dbtp = _dbtp_spinbutton.get_value ();
+ float lufs_i = _lufs_i_spinbutton.get_value ();
+ float lufs_s = _lufs_s_spinbutton.get_value ();
+ float lufs_m = _lufs_m_spinbutton.get_value ();
- float gain = 0;
- bool set = false;
+ float gain = 0;
+ bool set = false;
-#define MIN_IF_SET(A, B) \
- { if (set) { gain = std::min (gain, (A) - (B));} else { gain = (A) - (B); } set = true; }
+#define MIN_IF_SET(A, B) \
+ { \
+ if (set) { \
+ gain = std::min (gain, (A) - (B)); \
+ } else { \
+ gain = (A) - (B); \
+ } \
+ set = true; \
+ }
if (_dbfs_btn.get_active () && _dbfs_btn.sensitive ()) {
MIN_IF_SET (dbfs, _dbfs);
@@ -659,7 +771,7 @@ LoudnessDialog::calculate_gain ()
_delta_lufs_s_label.set_sensitive (_lufs_s_btn.get_active ());
_delta_lufs_m_label.set_sensitive (_lufs_m_btn.get_active ());
- _gain_norm = gain;
+ _gain_norm = gain;
bool in_range = gain_db () >= -40 && gain_db () <= 40;
_gain_norm_label.set_text (string_compose (_("%1 dB"), std::setprecision (2), std::showpos, std::fixed, _gain_norm));
@@ -668,89 +780,119 @@ LoudnessDialog::calculate_gain ()
_gain_total_label.set_markup (_(" \u00B140 dB"));
} else {
_gain_exceeds_label.set_text (X_(""));
- _gain_total_label.set_markup (string_compose (_("%1 dB"), std::setw(7), std::setprecision (2), std::showpos, std::fixed, gain_db ()));
+ _gain_total_label.set_markup (string_compose (_("%1 dB"), std::setw (7), std::setprecision (2), std::showpos, std::fixed, gain_db ()));
}
test_conformity ();
_ok_button->set_sensitive (in_range);
}
-void
-LoudnessDialog::toggle_conformity_display ()
-{
- if (_conformity_expander.get_expanded ()) {
- test_conformity ();
- } else {
- const int child_height = _conformity_expander.get_child ()->get_height ();
- _conformity_expander.remove ();
-
- Gtk::Requisition wr;
- get_size (wr.width, wr.height);
- wr.height -= child_height;
- resize (wr.width, wr.height);
- }
-}
-
void
LoudnessDialog::test_conformity ()
{
- if (!_conformity_expander.get_expanded ()) {
- return;
- }
- if (_conformity_expander.get_child ()) {
- _conformity_expander.remove ();
+ if (_conformity_frame.get_child ()) {
+ _conformity_frame.remove ();
}
const float dbfs = rintf ((_dbfs + _gain_norm) * 10.f) / 10.f;
const float dbtp = rintf ((_dbtp + _gain_norm) * 10.f) / 10.f;
const float lufs_i = rintf ((_lufs_i + _gain_norm) * 10.f) / 10.f;
- Table* t = manage (new Table ());
- size_t n_pset = sizeof (presets) / sizeof (LoudnessDialog::LoudnessPreset);
+ Table* t = manage (new Table ());
+ size_t n_pset = _lp.n_presets ();
size_t n_rows = ceil (n_pset / 3.0);
size_t row = 0;
size_t col = 0;
- uint32_t c_good = UIConfigurationBase::instance().color ("alert:green"); // OK / green
- uint32_t c_warn = UIConfigurationBase::instance().color ("alert:yellow"); // Warning / yellow
- uint32_t c_fail = UIConfigurationBase::instance().color ("alert:red"); // Fail / red
+ uint32_t c_good = UIConfigurationBase::instance ().color ("alert:green"); // OK / green
+ uint32_t c_warn = UIConfigurationBase::instance ().color ("alert:yellow"); // Warning / yellow
+ uint32_t c_fail = UIConfigurationBase::instance ().color ("alert:red"); // Fail / red
Gdk::Color color_good = ARDOUR_UI_UTILS::gdk_color_from_rgba (c_good);
Gdk::Color color_warn = ARDOUR_UI_UTILS::gdk_color_from_rgba (c_warn);
Gdk::Color color_fail = ARDOUR_UI_UTILS::gdk_color_from_rgba (c_fail);
for (size_t i = 1; i < n_pset; ++i) {
- Label* l = manage (new Label (presets[i].name + ":", ALIGN_LEFT));
- t->attach (*l, col, col + 1, row, row + 1, EXPAND|FILL, SHRINK, 2, 0);
+ CLoudnessPreset const& preset = _lp[i];
+ Label* l = manage (new Label (preset.label + ":", ALIGN_LEFT));
+ t->attach (*l, col, col + 1, row, row + 1, EXPAND | FILL, SHRINK, 2, 0);
- if (lufs_i > presets[i].max_integrated[0]
- || (presets[i].enable[0] && dbfs > presets[i].level[0])
- || (presets[i].enable[1] && dbtp > presets[i].level[1])
+ if (lufs_i > preset.LUFS_range[0]
+ || (preset.enable[0] && dbfs > preset.level[0])
+ || (preset.enable[1] && dbtp > preset.level[1])
) {
- l = manage (new Label ("\u274C", ALIGN_CENTER)); // "X"
+ l = manage (new Label ("\u274C", ALIGN_CENTER)); // cross mark
+ l->modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
l->modify_fg (Gtk::STATE_NORMAL, color_fail);
+ Gtkmm2ext::set_size_request_to_display_given_text (*l, "\u274C\u2714", 0, 0);
set_tooltip (*l, "The signal is too loud.");
- } else if (lufs_i < presets[i].max_integrated[1]) {
- l = manage (new Label ("\u2713", ALIGN_CENTER)); // "check-mark" - maybe use inv-box: \u274C
+ } else if (lufs_i < preset.LUFS_range[1]) {
+ l = manage (new Label ("\u2714", ALIGN_CENTER)); // heavy check mark
+ l->modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
l->modify_fg (Gtk::STATE_NORMAL, color_warn);
+ Gtkmm2ext::set_size_request_to_display_given_text (*l, "\u274C\u2714", 0, 0);
set_tooltip (*l, "The signal is too quiet, but satisfies the max. loudness spec.");
} else {
- l = manage (new Label ("\u2713", ALIGN_CENTER)); // "check-mark"
+ l = manage (new Label ("\u2714", ALIGN_CENTER)); // heavy check mark
+ l->modify_font (UIConfiguration::instance ().get_NormalMonospaceFont ());
l->modify_fg (Gtk::STATE_NORMAL, color_good);
set_tooltip (*l, "Signal loudness is within the spec.");
+ Gtkmm2ext::set_size_request_to_display_given_text (*l, "\u274C\u2714", 0, 0);
}
t->attach (*l, col + 1, col + 2, row, row + 1, SHRINK, SHRINK, 2, 0);
if (++row == n_rows) {
ArdourVSpacer* spc = manage (new ArdourVSpacer (1.0));
- t->attach (*spc, col + 2, col + 3, 0, n_rows, FILL, EXPAND|FILL, 8, 0);
+ t->attach (*spc, col + 2, col + 3, 0, n_rows, FILL, EXPAND | FILL, 8, 0);
row = 0;
col += 3;
}
}
- _conformity_expander.add (*t);
- _conformity_expander.show_all ();
+ t->set_border_width (6);
+ _conformity_frame.add (*t);
+ _conformity_frame.show_all ();
+}
+
+void
+LoudnessDialog::graph_size_request (Gtk::Requisition* req)
+{
+ if (_loudness_surf) {
+ req->width = _loudness_surf->get_width ();
+ req->height = _loudness_surf->get_height ();
+ } else {
+ req->width = 1;
+ req->height = 1;
+ }
+}
+
+bool
+LoudnessDialog::graph_expose_event (GdkEventExpose* ev)
+{
+ Cairo::RefPtr cr = _loudness_graph.get_window ()->create_cairo_context ();
+#if 0
+ Gtk::Allocation a = _loudness_graph.get_allocation ();
+ double const width = a.get_width ();
+ double const height = a.get_height ();
+#endif
+
+ cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
+ cr->clip ();
+
+ if (_loudness_surf) {
+ cr->set_source (_loudness_surf, 0, 0);
+ cr->set_operator (Cairo::OPERATOR_OVER);
+ cr->paint ();
+ }
+
+ return true;
+}
+
+void
+LoudnessDialog::plot_graph (ExportAnalysisPtr p)
+{
+ _loudness_surf = ArdourGraphs::plot_loudness (get_pango_context (), p, -1, 0, _session->nominal_sample_rate ());
+ _loudness_graph.queue_resize ();
}
diff --git a/gtk2_ardour/loudness_dialog.h b/gtk2_ardour/loudness_dialog.h
index 3a3c98abda..0780f7bb9d 100644
--- a/gtk2_ardour/loudness_dialog.h
+++ b/gtk2_ardour/loudness_dialog.h
@@ -19,8 +19,10 @@
#ifndef _gtkardour_loudness_dialog_h_
#define _gtkardour_loudness_dialog_h_
+#include
#include
-#include
+#include
+#include
#include
#include
#include
@@ -31,9 +33,11 @@
#include "ardour_dialog.h"
#include "progress_reporter.h"
+#include "loudness_settings.h"
namespace ARDOUR {
class AudioRange;
+ class ExportAnalysis;
class ExportStatus;
class PluginInsert;
class Processor;
@@ -58,26 +62,28 @@ private:
gint progress_timeout ();
void display_results ();
void display_report ();
+ void save_preset ();
+ void remove_preset ();
void calculate_gain ();
void load_preset (size_t);
void apply_preset ();
+ void peak_radio (bool);
void update_settings ();
+ void check_preset ();
void update_sensitivity ();
void test_conformity ();
- void toggle_conformity_display ();
- struct LoudnessPreset
- {
- std::string name;
- bool enable[5];
- float level[5];
- float max_integrated[2];
- };
+ void plot_graph (boost::shared_ptr);
+ void graph_size_request (Gtk::Requisition*);
+ bool graph_expose_event (GdkEventExpose*);
- static LoudnessPreset presets[];
- static LoudnessPreset _preset;
+ ALoudnessPresets _lp;
+ CLoudnessPreset _preset;
+
+ static bool _first_time;
+ static CLoudnessPreset _last_preset;
ARDOUR::Session* _session;
ARDOUR::AudioRange const& _range;
@@ -87,34 +93,41 @@ private:
Gtk::VBox _setup_box;
Gtk::VBox _progress_box;
Gtk::VBox _result_box;
- Gtk::Expander _conformity_expander;
+ Gtk::Frame _conformity_frame;
Gtk::ProgressBar _progress_bar;
Gtk::Button* _ok_button;
Gtk::Button* _cancel_button;
+ ArdourWidgets::ArdourButton _save_preset;
+ ArdourWidgets::ArdourButton _remove_preset;
+
ArdourWidgets::ArdourButton _dbfs_btn;
ArdourWidgets::ArdourButton _dbtp_btn;
ArdourWidgets::ArdourButton _lufs_i_btn;
ArdourWidgets::ArdourButton _lufs_s_btn;
ArdourWidgets::ArdourButton _lufs_m_btn;
- Gtk::Label _dbfs_label;
- Gtk::Label _dbtp_label;
- Gtk::Label _lufs_i_label;
- Gtk::Label _lufs_s_label;
- Gtk::Label _lufs_m_label;
+ Gtk::Label _dbfs_label;
+ Gtk::Label _dbtp_label;
+ Gtk::Label _lufs_i_label;
+ Gtk::Label _lufs_s_label;
+ Gtk::Label _lufs_m_label;
- Gtk::Label _delta_dbfs_label;
- Gtk::Label _delta_dbtp_label;
- Gtk::Label _delta_lufs_i_label;
- Gtk::Label _delta_lufs_s_label;
- Gtk::Label _delta_lufs_m_label;
+ Gtk::Label _delta_dbfs_label;
+ Gtk::Label _delta_dbtp_label;
+ Gtk::Label _delta_lufs_i_label;
+ Gtk::Label _delta_lufs_s_label;
+ Gtk::Label _delta_lufs_m_label;
- Gtk::Label _gain_out_label;
- Gtk::Label _gain_amp_label;
- Gtk::Label _gain_norm_label;
- Gtk::Label _gain_total_label;
- Gtk::Label _gain_exceeds_label;
+ Gtk::Label _gain_out_label;
+ Gtk::Label _gain_amp_label;
+ Gtk::Label _gain_norm_label;
+ Gtk::Label _gain_total_label;
+ Gtk::Label _gain_exceeds_label;
+
+ Gtk::DrawingArea _loudness_graph;
+
+ Cairo::RefPtr _loudness_surf;
ArdourWidgets::ArdourButton _rt_analysis_button;
ArdourWidgets::ArdourButton _start_analysis_button;
@@ -122,19 +135,18 @@ private:
ArdourWidgets::ArdourButton _custom_pos_button;
ArdourWidgets::ArdourDropdown _preset_dropdown;
- std::string _initial_preset_name;
- Gtk::Adjustment _dbfs_adjustment;
- Gtk::Adjustment _dbtp_adjustment;
- Gtk::Adjustment _lufs_i_adjustment;
- Gtk::Adjustment _lufs_s_adjustment;
- Gtk::Adjustment _lufs_m_adjustment;
+ Gtk::Adjustment _dbfs_adjustment;
+ Gtk::Adjustment _dbtp_adjustment;
+ Gtk::Adjustment _lufs_i_adjustment;
+ Gtk::Adjustment _lufs_s_adjustment;
+ Gtk::Adjustment _lufs_m_adjustment;
Gtk::SpinButton _dbfs_spinbutton;
- Gtk::SpinButton _dbtp_spinbutton;
- Gtk::SpinButton _lufs_i_spinbutton;
- Gtk::SpinButton _lufs_s_spinbutton;
- Gtk::SpinButton _lufs_m_spinbutton;
+ Gtk::SpinButton _dbtp_spinbutton;
+ Gtk::SpinButton _lufs_i_spinbutton;
+ Gtk::SpinButton _lufs_s_spinbutton;
+ Gtk::SpinButton _lufs_m_spinbutton;
float _dbfs;
float _dbtp;