2 Copyright (C) 2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <gtkmm/table.h>
21 #include <gtkmm/label.h>
22 #include <gtkmm/stock.h>
23 #include "ardour/audioregion.h"
24 #include "ardour/audiosource.h"
26 #include "ardour/dB.h"
27 #include "ardour_ui.h"
28 #include "gui_thread.h"
29 #include "strip_silence_dialog.h"
30 #include "canvas_impl.h"
32 #include "simplerect.h"
33 #include "rgb_macros.h"
36 using namespace ARDOUR
;
38 /** Construct Strip silence dialog box */
39 StripSilenceDialog::StripSilenceDialog (std::list
<boost::shared_ptr
<ARDOUR::AudioRegion
> > const & regions
)
40 : ArdourDialog (_("Strip Silence")), _wave_width (640), _wave_height (64)
42 for (std::list
<boost::shared_ptr
<ARDOUR::AudioRegion
> >::const_iterator i
= regions
.begin(); i
!= regions
.end(); ++i
) {
47 w
.samples_per_unit
= 1;
52 Gtk::HBox
* hbox
= Gtk::manage (new Gtk::HBox
);
53 hbox
->set_spacing (16);
55 Gtk::Table
* table
= Gtk::manage (new Gtk::Table (4, 3));
56 table
->set_spacings (4);
58 Gtk::Label
* l
= Gtk::manage (new Gtk::Label (_("Threshold:")));
59 l
->set_alignment (1, 0.5);
60 table
->attach (*l
, 0, 1, 0, 1, Gtk::FILL
, Gtk::FILL
);
61 _threshold
.set_digits (1);
62 _threshold
.set_increments (1, 10);
63 _threshold
.set_range (-120, 0);
64 _threshold
.set_value (-60);
65 table
->attach (_threshold
, 1, 2, 0, 1, Gtk::FILL
, Gtk::FILL
);
66 l
= Gtk::manage (new Gtk::Label (_("dBFS")));
67 l
->set_alignment (0, 0.5);
68 table
->attach (*l
, 2, 3, 0, 1, Gtk::FILL
, Gtk::FILL
);
70 l
= Gtk::manage (new Gtk::Label (_("Minimum length:")));
71 l
->set_alignment (1, 0.5);
72 table
->attach (*l
, 0, 1, 1, 2, Gtk::FILL
, Gtk::FILL
);
73 _minimum_length
.set_digits (0);
74 _minimum_length
.set_increments (1, 10);
75 _minimum_length
.set_range (0, 65536);
76 _minimum_length
.set_value (256);
77 table
->attach (_minimum_length
, 1, 2, 1, 2, Gtk::FILL
, Gtk::FILL
);
78 l
= Gtk::manage (new Gtk::Label (_("samples")));
79 table
->attach (*l
, 2, 3, 1, 2, Gtk::FILL
, Gtk::FILL
);
81 l
= Gtk::manage (new Gtk::Label (_("Fade length:")));
82 l
->set_alignment (1, 0.5);
83 table
->attach (*l
, 0, 1, 2, 3, Gtk::FILL
, Gtk::FILL
);
84 _fade_length
.set_digits (0);
85 _fade_length
.set_increments (1, 10);
86 _fade_length
.set_range (0, 1024);
87 _fade_length
.set_value (64);
88 table
->attach (_fade_length
, 1, 2, 2, 3, Gtk::FILL
, Gtk::FILL
);
89 l
= Gtk::manage (new Gtk::Label (_("samples")));
90 table
->attach (*l
, 2, 3, 2, 3, Gtk::FILL
, Gtk::FILL
);
92 hbox
->pack_start (*table
, false, false);
94 Gtk::VBox
* v
= Gtk::manage (new Gtk::VBox
);
95 Gtk::Button
* b
= Gtk::manage (new Gtk::Button (_("Update display")));
96 b
->signal_clicked().connect (sigc::mem_fun (*this, &StripSilenceDialog::update_silence_rects
));
97 v
->pack_start (*b
, false, false);
98 hbox
->pack_start (*v
, false, false);
100 get_vbox()->add (*hbox
);
102 add_button (Gtk::Stock::CANCEL
, Gtk::RESPONSE_CANCEL
);
103 add_button (Gtk::Stock::APPLY
, Gtk::RESPONSE_OK
);
105 _canvas
= new ArdourCanvas::CanvasAA ();
106 _canvas
->signal_size_allocate().connect (sigc::mem_fun (*this, &StripSilenceDialog::canvas_allocation
));
107 _canvas
->set_size_request (_wave_width
, _wave_height
* _waves
.size ());
109 get_vbox()->pack_start (*_canvas
, true, true);
114 update_silence_rects ();
118 StripSilenceDialog::~StripSilenceDialog ()
120 for (std::list
<Wave
>::iterator i
= _waves
.begin(); i
!= _waves
.end(); ++i
) {
122 for (std::list
<ArdourCanvas::SimpleRect
*>::iterator j
= i
->silence_rects
.begin(); j
!= i
->silence_rects
.end(); ++j
) {
131 StripSilenceDialog::create_waves ()
135 for (std::list
<Wave
>::iterator i
= _waves
.begin(); i
!= _waves
.end(); ++i
) {
136 if (i
->region
->audio_source(0)->peaks_ready (boost::bind (&StripSilenceDialog::peaks_ready
, this), _peaks_ready_connection
, gui_context())) {
137 i
->view
= new WaveView (*(_canvas
->root()));
138 i
->view
->property_data_src() = static_cast<gpointer
>(i
->region
.get());
139 i
->view
->property_cache() = WaveView::create_cache ();
140 i
->view
->property_cache_updater() = true;
141 i
->view
->property_channel() = 0;
142 i
->view
->property_length_function() = (void *) region_length_from_c
;
143 i
->view
->property_sourcefile_length_function() = (void *) sourcefile_length_from_c
;
144 i
->view
->property_peak_function() = (void *) region_read_peaks_from_c
;
145 i
->view
->property_x() = 0;
146 i
->view
->property_y() = n
* _wave_height
;
147 i
->view
->property_height() = _wave_height
;
148 i
->view
->property_samples_per_unit() = i
->samples_per_unit
;
149 i
->view
->property_region_start() = i
->region
->start();
150 i
->view
->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm
.get();
151 i
->view
->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill
.get();
159 StripSilenceDialog::peaks_ready ()
161 _peaks_ready_connection
.disconnect ();
166 StripSilenceDialog::canvas_allocation (Gtk::Allocation
& alloc
)
168 _canvas
->set_scroll_region (0.0, 0.0, alloc
.get_width(), alloc
.get_height());
169 _wave_width
= alloc
.get_width ();
171 for (std::list
<Wave
>::iterator i
= _waves
.begin(); i
!= _waves
.end(); ++i
) {
172 i
->samples_per_unit
= ((double) i
->region
->length() / _wave_width
);
177 StripSilenceDialog::update_silence_rects ()
181 for (std::list
<Wave
>::iterator i
= _waves
.begin(); i
!= _waves
.end(); ++i
) {
182 for (std::list
<ArdourCanvas::SimpleRect
*>::iterator j
= i
->silence_rects
.begin(); j
!= i
->silence_rects
.end(); ++j
) {
186 i
->silence_rects
.clear ();
188 std::list
<std::pair
<frameoffset_t
, framecnt_t
> > const silence
=
189 i
->region
->find_silence (dB_to_coefficient (threshold ()), minimum_length ());
191 for (std::list
<std::pair
<frameoffset_t
, framecnt_t
> >::const_iterator j
= silence
.begin(); j
!= silence
.end(); ++j
) {
193 ArdourCanvas::SimpleRect
* r
= new ArdourCanvas::SimpleRect (*(_canvas
->root()));
194 r
->property_x1() = j
->first
/ i
->samples_per_unit
;
195 r
->property_x2() = j
->second
/ i
->samples_per_unit
;
196 r
->property_y1() = n
* _wave_height
;
197 r
->property_y2() = (n
+ 1) * _wave_height
;
198 r
->property_outline_pixels() = 0;
199 r
->property_fill_color_rgba() = RGBA_TO_UINT (128, 128, 128, 128);
200 i
->silence_rects
.push_back (r
);