Cont'd work on loudness analysis
This commit is contained in:
parent
5ff3453b30
commit
2829ba5150
@ -127,7 +127,7 @@ Editor::measure_master_loudness (bool range_selection)
|
||||
float prev_gain = _session->master_volume()->get_value();
|
||||
_session->master_volume ()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup);
|
||||
|
||||
LoudnessDialog ld (_session, ar);
|
||||
LoudnessDialog ld (_session, ar, range_selection);
|
||||
|
||||
if (ld.run () == RESPONSE_APPLY) {
|
||||
_session->master_volume ()->set_value (dB_to_coefficient (ld.gain_db ()), Controllable::NoGroup);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "ardour/export_status.h"
|
||||
#include "ardour/export_timespan.h"
|
||||
|
||||
#include "widgets/ardour_spacer.h"
|
||||
|
||||
#include "export_report.h"
|
||||
#include "loudness_dialog.h"
|
||||
|
||||
@ -37,80 +39,134 @@
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace ARDOUR;
|
||||
using namespace ArdourWidgets;
|
||||
|
||||
LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar)
|
||||
LoudnessDialog::LoudnessDialog (Session* s, AudioRange const& ar, bool as)
|
||||
: ArdourDialog (_("Loudness Mate"))
|
||||
, _session (s)
|
||||
, _range (ar)
|
||||
, _status (s->get_export_status ())
|
||||
, _report_button (_("Show"))
|
||||
, _autostart (as)
|
||||
, _rt_analysis_button (_("Realtime"), ArdourButton::led_default_elements, true)
|
||||
, _start_analysis_button (_("Analyze"))
|
||||
, _show_report_button (_("Show Detailed Report"))
|
||||
, _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_adjustment (-23.0, -90.00, 0.00, 0.1, 1.0)
|
||||
, _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_spinbutton (_dbfs_adjustment, 0.1, 1)
|
||||
, _dbtp_spinbutton (_dbtp_adjustment, 0.1, 1)
|
||||
, _lufs_spinbutton (_lufs_adjustment, 0.1, 1)
|
||||
, _lufs_i_spinbutton (_lufs_i_adjustment, 0.1, 1)
|
||||
, _lufs_s_spinbutton (_lufs_s_adjustment, 0.1, 1)
|
||||
, _lufs_m_spinbutton (_lufs_m_adjustment, 0.1, 1)
|
||||
, _gain (0)
|
||||
{
|
||||
Gtk::Label* l;
|
||||
Gtk::Table* t = manage (new Table (8, 3, false));
|
||||
_start_analysis_button.set_name ("generic button");
|
||||
_rt_analysis_button.set_name ("generic button");
|
||||
_show_report_button.set_name ("generic button");
|
||||
|
||||
Label* l;
|
||||
Table* t = manage (new Table (8, 3, false));
|
||||
t->set_spacings (4);
|
||||
l = manage (new Label (_("<b>Measured</b>"), Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 1, 2, 0, 1);
|
||||
l = manage (new Label (_("<b>Target</b>"), Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 2, 3, 0, 1);
|
||||
|
||||
l = manage (new Label (_("Digital Peak:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
t->attach (*l, 0, 1, 1, 2);
|
||||
l = manage (new Label (_("Analog Peak:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l = manage (new Label (_("<b>Analysis Results</b>"), ALIGN_LEFT));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 0, 1, 0, 1);
|
||||
t->attach (_show_report_button, 1, 4, 0, 1);
|
||||
|
||||
l = manage (new Label (_("<b>Measured</b>"), ALIGN_CENTER));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 1, 2, 1, 2);
|
||||
l = manage (new Label (_("<b>Target</b>"), ALIGN_CENTER));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 2, 3, 1, 2);
|
||||
l = manage (new Label (_("<b>Delta</b>"), ALIGN_CENTER));
|
||||
l->set_use_markup (true);
|
||||
t->attach (*l, 3, 4, 1, 2);
|
||||
|
||||
l = manage (new Label (_("Peak:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 2, 3);
|
||||
l = manage (new Label (_("Integrated Loudness:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l = manage (new Label (_("True Peak:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 3, 4);
|
||||
l = manage (new Label (_("Max. Short Loudness:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l = manage (new Label (_("Integrated Loudness:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 4, 5);
|
||||
l = manage (new Label (_("Max. Momentary Loudness:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l = manage (new Label (_("Max. Short Loudness:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 5, 6);
|
||||
l = manage (new Label (_("Detailed Report:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
l = manage (new Label (_("Max. Momentary Loudness:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 6, 7);
|
||||
l = manage (new Label (_("Suggested Gain:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
|
||||
t->attach (*l, 0, 1, 7, 8);
|
||||
l = manage (new Label (_("Suggested Gain:"), ALIGN_LEFT));
|
||||
t->attach (*l, 0, 1, 8, 9);
|
||||
|
||||
t->attach (_dbfs_label, 1, 2, 1, 2);
|
||||
t->attach (_dbtp_label, 1, 2, 2, 3);
|
||||
t->attach (_lufs_integrated_label, 1, 2, 3, 4);
|
||||
t->attach (_lufs_short_label, 1, 2, 4, 5);
|
||||
t->attach (_lufs_momentary_label, 1, 2, 5, 6);
|
||||
t->attach (_report_button, 1, 2, 6, 7);
|
||||
t->attach (_gain_label, 1, 2, 7, 8);
|
||||
t->attach (_dbfs_label, 1, 2, 2, 3);
|
||||
t->attach (_dbtp_label, 1, 2, 3, 4);
|
||||
t->attach (_lufs_i_label, 1, 2, 4, 5);
|
||||
t->attach (_lufs_s_label, 1, 2, 5, 6);
|
||||
t->attach (_lufs_m_label, 1, 2, 6, 7);
|
||||
|
||||
t->attach (_dbfs_spinbutton, 2, 3, 1, 2);
|
||||
t->attach (_dbtp_spinbutton, 2, 3, 2, 3);
|
||||
t->attach (_lufs_spinbutton, 2, 3, 3, 4);
|
||||
t->attach (_dbfs_spinbutton, 2, 3, 2, 3);
|
||||
t->attach (_dbtp_spinbutton, 2, 3, 3, 4);
|
||||
t->attach (_lufs_i_spinbutton, 2, 3, 4, 5);
|
||||
t->attach (_lufs_s_spinbutton, 2, 3, 5, 6);
|
||||
t->attach (_lufs_m_spinbutton, 2, 3, 6, 7);
|
||||
|
||||
_report_button.set_name ("generic button");
|
||||
t->attach (_delta_dbfs_label, 3, 4, 2, 3);
|
||||
t->attach (_delta_dbtp_label, 3, 4, 3, 4);
|
||||
t->attach (_delta_lufs_i_label, 3, 4, 4, 5);
|
||||
t->attach (_delta_lufs_s_label, 3, 4, 5, 6);
|
||||
t->attach (_delta_lufs_m_label, 3, 4, 6, 7);
|
||||
|
||||
ArdourHSpacer* spc = manage (new ArdourHSpacer (1.0));
|
||||
t->attach (*spc , 1, 4, 7, 8);
|
||||
t->attach (_gain_label, 3, 4, 8, 9);
|
||||
|
||||
_result_box.pack_start (*t, false, false, 6);
|
||||
_progress_box.pack_start (_progress_bar, false, false, 6);
|
||||
|
||||
t = manage (new Table (2, 3, false));
|
||||
t->set_spacings (4);
|
||||
l = manage (new Label ());
|
||||
l->set_line_wrap ();
|
||||
l->set_markup (_(
|
||||
"<b>Loudness Analysis</b>\n\n"
|
||||
"This allows to analyze the loudness of of the signal at the master-bus "
|
||||
"output of the complete session, as it would be exported.\n"
|
||||
"The result an be used to interactively normalize the session's loudnless level "
|
||||
"(as opposed to automatical normalization during export).\n"
|
||||
"By default a faster than realtime export is is used to asses the loudness of the "
|
||||
"session. If any outboard gear is used, a <i>realtime</i> export is available, to "
|
||||
"play at normal speed.\n"
|
||||
));
|
||||
t->attach (*l, 1, 4, 1, 2, EXPAND|FILL, EXPAND|FILL, 0, 8);
|
||||
l = manage (new Label (""));
|
||||
t->attach (*l, 1, 2, 2, 3);
|
||||
t->attach (_rt_analysis_button, 2, 3, 2, 3, FILL, SHRINK);
|
||||
t->attach (_start_analysis_button, 3, 4, 2, 3, FILL, SHRINK);
|
||||
_setup_box.pack_start (*t, false, false, 6);
|
||||
|
||||
get_vbox()->pack_start (_setup_box);
|
||||
get_vbox()->pack_start (_progress_box);
|
||||
get_vbox()->pack_start (_result_box);
|
||||
get_vbox()->set_size_request(400,-1);
|
||||
|
||||
_ok_button = add_button (Gtk::Stock::APPLY, RESPONSE_APPLY);
|
||||
_cancel_button = add_button (Gtk::Stock::CANCEL, RESPONSE_CANCEL);
|
||||
_ok_button = add_button (Stock::APPLY, RESPONSE_APPLY);
|
||||
_cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||
|
||||
_cancel_button->signal_clicked().connect (sigc::mem_fun (this, &LoudnessDialog::cancel_analysis));
|
||||
_dbfs_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_dbtp_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_lufs_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_report_button.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::display_report));
|
||||
_lufs_i_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_lufs_s_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_lufs_m_spinbutton.signal_value_changed().connect (mem_fun (*this, &LoudnessDialog::calculate_gain));
|
||||
_show_report_button.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::display_report));
|
||||
_start_analysis_button.signal_clicked.connect (mem_fun (*this, &LoudnessDialog::start_analysis));
|
||||
|
||||
_ok_button->set_sensitive (false);
|
||||
_report_button.set_sensitive (false);
|
||||
_show_report_button.set_sensitive (false);
|
||||
show_all_children ();
|
||||
|
||||
_result_box.hide ();
|
||||
_progress_box.hide ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -121,6 +177,16 @@ LoudnessDialog::cancel_analysis ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoudnessDialog::start_analysis ()
|
||||
{
|
||||
if (0 == analyze ()) {
|
||||
display_results ();
|
||||
} else {
|
||||
_setup_box.show ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LoudnessDialog::on_delete_event (GdkEventAny*)
|
||||
{
|
||||
@ -131,23 +197,14 @@ LoudnessDialog::on_delete_event (GdkEventAny*)
|
||||
int
|
||||
LoudnessDialog::run ()
|
||||
{
|
||||
#if 1
|
||||
// TODO: consider interactive analysis "start" button,
|
||||
// after settings, e.g. realtime export, IO select
|
||||
show ();
|
||||
switch (analyze ()) {
|
||||
case 0:
|
||||
/* OK */
|
||||
if (_autostart) {
|
||||
show ();
|
||||
if (0 == analyze ()) {
|
||||
display_results ();
|
||||
break;
|
||||
case 1:
|
||||
/* aborted */
|
||||
return RESPONSE_CANCEL;
|
||||
default:
|
||||
// TODO show an ArdourMessageDialog here or in parent Editor::analyze_range_export
|
||||
} else {
|
||||
return RESPONSE_CANCEL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int const r = ArdourDialog::run ();
|
||||
cancel_analysis ();
|
||||
@ -166,18 +223,11 @@ LoudnessDialog::progress_timeout ()
|
||||
int
|
||||
LoudnessDialog::analyze ()
|
||||
{
|
||||
/* add master outs as default */
|
||||
IO* master_out = _session->master_out()->output().get();
|
||||
if (!master_out) {
|
||||
return -1;
|
||||
}
|
||||
if (master_out->n_ports().n_audio() != 2) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (_range.start >= _range.end) {
|
||||
return -3;
|
||||
}
|
||||
/* These are ensured in Editor::measure_master_loudness () */
|
||||
assert (_session->master_out());
|
||||
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();
|
||||
|
||||
@ -196,12 +246,13 @@ LoudnessDialog::analyze ()
|
||||
fmp->set_analyse (true);
|
||||
|
||||
/* setup range */
|
||||
// TODO: consider multiple ranges
|
||||
tsp->set_range (_range.start, _range.end);
|
||||
tsp->set_range_id ("selection");
|
||||
tsp->set_realtime (false);
|
||||
tsp->set_realtime (_rt_analysis_button.get_active ());
|
||||
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 ();
|
||||
channel->add_port (master_out->audio (n));
|
||||
@ -216,6 +267,14 @@ LoudnessDialog::analyze ()
|
||||
_session->get_export_handler()->do_export();
|
||||
|
||||
/* show progress */
|
||||
_setup_box.hide ();
|
||||
_progress_box.show_all ();
|
||||
|
||||
/* shrink window height (setup box) */
|
||||
Gtk::Requisition wr;
|
||||
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);
|
||||
|
||||
while (_status->running ()) {
|
||||
@ -236,8 +295,10 @@ LoudnessDialog::analyze ()
|
||||
void
|
||||
LoudnessDialog::display_report ()
|
||||
{
|
||||
hide ();
|
||||
ExportReport er ("Export Loudness Report", _status->result_map);
|
||||
er.run();
|
||||
show ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -247,33 +308,45 @@ LoudnessDialog::display_results ()
|
||||
assert (ar.size () == 1);
|
||||
ExportAnalysisPtr p = ar.begin()->second;
|
||||
|
||||
_dbfs = accurate_coefficient_to_dB (p->peak);
|
||||
_dbtp = accurate_coefficient_to_dB (p->truepeak);
|
||||
_lufs = p->integrated_loudness;
|
||||
_dbfs = accurate_coefficient_to_dB (p->peak);
|
||||
_dbtp = accurate_coefficient_to_dB (p->truepeak);
|
||||
_lufs_i = p->integrated_loudness;
|
||||
_lufs_s = p->max_loudness_short;
|
||||
_lufs_m = p->max_loudness_momentary;
|
||||
|
||||
_dbfs_label.set_text (string_compose (_("%1 dBFS"), std::setprecision (1), std::fixed, _dbfs));
|
||||
_dbtp_label.set_text (string_compose (_("%1 dBTP"), std::setprecision (1), std::fixed, _dbtp));
|
||||
_lufs_integrated_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, _lufs));
|
||||
_lufs_short_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, p->max_loudness_short));
|
||||
_lufs_momentary_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, p->max_loudness_momentary));
|
||||
_lufs_i_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, _lufs_i));
|
||||
_lufs_s_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, _lufs_s));
|
||||
_lufs_m_label.set_text (string_compose (_("%1 LUFS"), std::setprecision (1), std::fixed, _lufs_m));
|
||||
|
||||
calculate_gain ();
|
||||
|
||||
_result_box.show_all ();
|
||||
_ok_button->set_sensitive (true);
|
||||
_report_button.set_sensitive (true);
|
||||
_show_report_button.set_sensitive (true);
|
||||
}
|
||||
|
||||
void
|
||||
LoudnessDialog::calculate_gain ()
|
||||
{
|
||||
float dbfs = _dbfs_spinbutton.get_value();
|
||||
float dbtp = _dbtp_spinbutton.get_value();
|
||||
float lufs = _lufs_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();
|
||||
|
||||
_gain = dbfs - _dbfs;
|
||||
_gain = std::min (_gain, dbtp - _dbtp);
|
||||
_gain = std::min (_gain, lufs - _lufs);
|
||||
_gain = std::min (_gain, lufs_i - _lufs_i);
|
||||
_gain = std::min (_gain, lufs_s - _lufs_s);
|
||||
_gain = std::min (_gain, lufs_m - _lufs_m);
|
||||
|
||||
_delta_dbfs_label.set_text (string_compose (_("%1 dB"), std::setprecision (2), std::fixed, dbfs - _dbfs));
|
||||
_delta_dbtp_label.set_text (string_compose (_("%1 dB"), std::setprecision (2), std::fixed, dbtp - _dbtp));
|
||||
_delta_lufs_i_label.set_text (string_compose (_("%1 LU"), std::setprecision (2), std::fixed, lufs_i - _lufs_i));
|
||||
_delta_lufs_s_label.set_text (string_compose (_("%1 LU"), std::setprecision (2), std::fixed, lufs_s - _lufs_s));
|
||||
_delta_lufs_m_label.set_text (string_compose (_("%1 LU"), std::setprecision (2), std::fixed, lufs_m - _lufs_m));
|
||||
|
||||
_gain_label.set_text (string_compose (_("%1 dB"), std::setprecision (2), std::fixed, _gain));
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace ARDOUR {
|
||||
class LoudnessDialog : public ArdourDialog
|
||||
{
|
||||
public:
|
||||
LoudnessDialog (ARDOUR::Session*, ARDOUR::AudioRange const&);
|
||||
LoudnessDialog (ARDOUR::Session*, ARDOUR::AudioRange const&, bool);
|
||||
int run ();
|
||||
float gain_db () const { return _gain; }
|
||||
|
||||
@ -45,6 +45,7 @@ protected:
|
||||
|
||||
private:
|
||||
int analyze ();
|
||||
void start_analysis ();
|
||||
void cancel_analysis ();
|
||||
gint progress_timeout ();
|
||||
void display_results ();
|
||||
@ -54,7 +55,9 @@ private:
|
||||
ARDOUR::Session* _session;
|
||||
ARDOUR::AudioRange const& _range;
|
||||
boost::shared_ptr<ARDOUR::ExportStatus> _status;
|
||||
bool _autostart;
|
||||
|
||||
Gtk::VBox _setup_box;
|
||||
Gtk::VBox _progress_box;
|
||||
Gtk::VBox _result_box;
|
||||
Gtk::ProgressBar _progress_bar;
|
||||
@ -63,23 +66,39 @@ private:
|
||||
|
||||
Gtk::Label _dbfs_label;
|
||||
Gtk::Label _dbtp_label;
|
||||
Gtk::Label _lufs_integrated_label;
|
||||
Gtk::Label _lufs_short_label;
|
||||
Gtk::Label _lufs_momentary_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 _gain_label;
|
||||
|
||||
ArdourWidgets::ArdourButton _report_button;
|
||||
ArdourWidgets::ArdourButton _rt_analysis_button;
|
||||
ArdourWidgets::ArdourButton _start_analysis_button;
|
||||
ArdourWidgets::ArdourButton _show_report_button;
|
||||
|
||||
Gtk::Adjustment _dbfs_adjustment;
|
||||
Gtk::Adjustment _dbtp_adjustment;
|
||||
Gtk::Adjustment _lufs_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_spinbutton;
|
||||
Gtk::SpinButton _lufs_i_spinbutton;
|
||||
Gtk::SpinButton _lufs_s_spinbutton;
|
||||
Gtk::SpinButton _lufs_m_spinbutton;
|
||||
|
||||
float _dbfs;
|
||||
float _dbtp;
|
||||
float _lufs;
|
||||
float _lufs_i;
|
||||
float _lufs_s;
|
||||
float _lufs_m;
|
||||
float _gain;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user