1 /*
2 * Copyright (C) 2010-2011 Carl Hetherington <carl@carlh.net>
3 * Copyright (C) 2016 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <gtkmm/table.h>
22 #include <gtkmm/label.h>
23 #include <gtkmm/spinbutton.h>
24 #include <gtkmm/radiobutton.h>
25 #include <gtkmm/stock.h>
26 #include <gtkmm/progressbar.h>
27 #include "normalize_dialog.h"
28 #include "pbd/i18n.h"
29
30 using namespace Gtk;
31
32 double NormalizeDialog::_last_normalization_value = 0;
33 double NormalizeDialog::_last_rms_target_value = -9;
34 bool NormalizeDialog::_last_normalize_individually = true;
35 bool NormalizeDialog::_last_constrain_rms = false;
36
NormalizeDialog(bool more_than_one)37 NormalizeDialog::NormalizeDialog (bool more_than_one)
38 : ArdourDialog (more_than_one ? _("Normalize regions") : _("Normalize region"))
39 , _normalize_individually (0)
40 {
41 get_vbox()->set_spacing (12);
42
43 Table* tbl = manage (new Table);
44 tbl->set_spacings (6);
45 tbl->set_border_width (6);
46
47 _spin_peak = manage (new SpinButton (0.2, 2));
48 _spin_peak->set_range (-112, 0);
49 _spin_peak->set_increments (0.1, 1);
50 _spin_peak->set_value (_last_normalization_value);
51 _spin_peak->set_activates_default ();
52
53 _constrain_rms = manage (new CheckButton (_("Constrain RMS to:")));
54 _constrain_rms->set_active (_last_constrain_rms);
55 _spin_rms = manage (new SpinButton (0.2, 2));
56 _spin_rms->set_range (-112, 0);
57 _spin_rms->set_increments (0.1, 1);
58 _spin_rms->set_value (_last_rms_target_value);
59
60 tbl->attach (*manage (new Label (_("Normalize to:"), ALIGN_END)), 0, 1, 0, 1, FILL, SHRINK);
61 tbl->attach (*_spin_peak, 1, 2, 0, 1, SHRINK, SHRINK);
62 tbl->attach (*manage (new Label (_("dBFS"))), 2, 3, 0, 1, SHRINK, SHRINK);
63
64 tbl->attach (*_constrain_rms, 0, 1, 1, 2, SHRINK, SHRINK);
65 tbl->attach (*_spin_rms, 1, 2, 1, 2, SHRINK, SHRINK);
66 tbl->attach (*manage (new Label (_("dBFS"))), 2, 3, 1, 2, SHRINK, SHRINK);
67
68 get_vbox()->pack_start (*tbl);
69
70 if (more_than_one) {
71 RadioButtonGroup group;
72 VBox* vbox = manage (new VBox);
73
74 _normalize_individually = manage (new RadioButton (group, _("Normalize each region using its own peak value")));
75 vbox->pack_start (*_normalize_individually);
76 RadioButton* b = manage (new RadioButton (group, _("Normalize each region using the peak value of all regions")));
77 vbox->pack_start (*b);
78
79 _normalize_individually->set_active (_last_normalize_individually);
80 b->set_active (!_last_normalize_individually);
81
82 get_vbox()->pack_start (*vbox);
83 }
84
85 _progress_bar = manage (new ProgressBar);
86 get_vbox()->pack_start (*_progress_bar);
87
88 update_sensitivity ();
89 show_all ();
90 _progress_bar->hide ();
91
92 add_button (Stock::CANCEL, RESPONSE_CANCEL);
93 add_button (_("Normalize"), RESPONSE_ACCEPT);
94 set_default_response (RESPONSE_ACCEPT);
95
96 _constrain_rms->signal_toggled ().connect (sigc::mem_fun (*this, &NormalizeDialog::update_sensitivity));
97 signal_response().connect (sigc::mem_fun (*this, &NormalizeDialog::button_clicked));
98 }
99
100 void
update_sensitivity()101 NormalizeDialog::update_sensitivity ()
102 {
103 _spin_rms->set_sensitive (constrain_rms ());
104 }
105
106 bool
normalize_individually() const107 NormalizeDialog::normalize_individually () const
108 {
109 if (_normalize_individually == 0) {
110 return true;
111 }
112
113 return _normalize_individually->get_active ();
114 }
115
116 bool
constrain_rms() const117 NormalizeDialog::constrain_rms () const
118 {
119 return _constrain_rms->get_active ();
120 }
121
122 double
target_peak() const123 NormalizeDialog::target_peak () const
124 {
125 return _spin_peak->get_value ();
126 }
127
128 double
target_rms() const129 NormalizeDialog::target_rms () const
130 {
131 return _spin_rms->get_value ();
132 }
133
134 void
update_progress_gui(float p)135 NormalizeDialog::update_progress_gui (float p)
136 {
137 /* Normalization is run inside the GUI thread, so we can directly
138 * update the progress bar when notified about progress.
139 */
140 _progress_bar->show ();
141 _progress_bar->set_fraction (p);
142 }
143
144 int
run()145 NormalizeDialog::run ()
146 {
147 int const r = ArdourDialog::run ();
148 _last_normalization_value = target_peak ();
149 _last_rms_target_value = target_rms ();
150 _last_constrain_rms = constrain_rms ();
151 if (_normalize_individually) {
152 _last_normalize_individually = _normalize_individually->get_active ();
153 }
154 return r;
155 }
156
157 void
button_clicked(int r)158 NormalizeDialog::button_clicked (int r)
159 {
160 if (r == RESPONSE_CANCEL) {
161 cancel ();
162 }
163 }
164