+
+ if (min_audible > 0) {
+ float ms, ma;
+ char const * aunits;
+ char const * sunits;
+
+ ma = (float) min_audible/_session->frame_rate();
+ ms = (float) min_silence/_session->frame_rate();
+
+ if (min_audible < _session->frame_rate()) {
+ aunits = _("ms");
+ ma *= 1000.0;
+ } else {
+ aunits = _("s");
+ }
+
+ if (min_silence < _session->frame_rate()) {
+ sunits = _("ms");
+ ms *= 1000.0;
+ } else {
+ sunits = _("s");
+ }
+
+ _segment_count_label.set_text (string_compose ("%1", max_segments));
+ if (max_segments > 0) {
+ _shortest_silence_label.set_text (string_compose ("%1 %2", ms, sunits));
+ _shortest_audible_label.set_text (string_compose ("%1 %2", ma, aunits));
+ } else {
+ _shortest_silence_label.set_text ("");
+ _shortest_audible_label.set_text ("");
+ }
+ } else {
+ _segment_count_label.set_text (_("Full silence"));
+ _shortest_silence_label.set_text ("");
+ _shortest_audible_label.set_text ("");
+ }
+}
+
+bool
+StripSilenceDialog::_detection_done (void* arg)
+{
+ StripSilenceDialog* ssd = (StripSilenceDialog*) arg;
+ return ssd->detection_done ();
+}
+
+bool
+StripSilenceDialog::detection_done ()
+{
+ get_window()->set_cursor (Gdk::Cursor (Gdk::LEFT_PTR));
+ update_silence_rects ();
+ return false;
+}
+
+void*
+StripSilenceDialog::_detection_thread_work (void* arg)
+{
+ StripSilenceDialog* ssd = (StripSilenceDialog*) arg;
+ return ssd->detection_thread_work ();
+}
+
+void*
+StripSilenceDialog::detection_thread_work ()
+{
+ ARDOUR_UI::instance()->register_thread ("gui", pthread_self(), "silence", 32);
+
+ while (1) {
+
+ run_lock.lock ();
+ thread_waiting->signal ();
+ thread_run->wait (run_lock);
+
+ if (thread_should_exit) {
+ thread_waiting->signal ();
+ run_lock.unlock ();
+ break;
+ }
+
+ if (current) {
+ StripSilenceDialog* ssd = current;
+ run_lock.unlock ();
+
+ for (list<Wave*>::iterator i = ssd->_waves.begin(); i != ssd->_waves.end(); ++i) {
+ (*i)->silence = (*i)->region->find_silence (dB_to_coefficient (ssd->threshold ()), ssd->minimum_length (), ssd->itt);
+ ssd->update_stats ((*i)->silence);
+ }
+
+ if (!ssd->itt.cancel) {
+ g_idle_add ((gboolean (*)(void*)) StripSilenceDialog::_detection_done, ssd);
+ }
+ } else {
+ run_lock.unlock ();
+ }
+
+ }
+
+ return 0;
+}
+
+void
+StripSilenceDialog::threshold_changed ()
+{
+ update_threshold_line ();
+ maybe_start_silence_detection ();
+}
+
+void
+StripSilenceDialog::maybe_start_silence_detection ()
+{
+ if (!restart_queued) {
+ restart_queued = true;
+ Glib::signal_idle().connect (sigc::mem_fun (*this, &StripSilenceDialog::start_silence_detection));
+ }
+}
+
+bool
+StripSilenceDialog::start_silence_detection ()
+{
+ Glib::Mutex::Lock lm (run_lock);
+ restart_queued = false;
+
+ if (!itt.thread) {
+
+ itt.done = false;
+ itt.cancel = false;
+ itt.progress = 0.0;
+ current = this;
+
+ pthread_create (&itt.thread, 0, StripSilenceDialog::_detection_thread_work, this);
+ /* wait for it to get started */
+ thread_waiting->wait (run_lock);
+
+ } else {
+
+ /* stop whatever the thread is doing */
+
+ itt.cancel = 1;
+ current = 0;
+
+ while (!itt.done) {
+ thread_run->signal ();
+ thread_waiting->wait (run_lock);
+ }
+ }
+
+
+ itt.cancel = false;
+ itt.done = false;
+ itt.progress = 0.0;
+ current = this;
+
+ /* and start it up (again) */
+
+ thread_run->signal ();
+
+ /* change cursor */
+
+ get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+
+ /* don't call again until needed */
+
+ return false;
+}
+
+void
+StripSilenceDialog::stop_thread ()
+{
+ Glib::Mutex::Lock lm (run_lock);
+
+ itt.cancel = true;
+ thread_should_exit = true;
+ thread_run->signal ();
+ thread_waiting->wait (run_lock);
+ itt.thread = 0;
+}
+
+void
+StripSilenceDialog::update_stats (const SilenceResult& res)
+{
+ if (res.empty()) {
+ return;
+ }
+
+ max_silence = 0;
+ min_silence = max_frames;
+ max_audible = 0;
+ min_audible = max_frames;
+
+ SilenceResult::const_iterator cur;
+
+ cur = res.begin();
+
+ framepos_t start = 0;
+ framepos_t end;
+ bool in_silence;
+
+ if (cur->first == 0) {
+ /* initial segment, starting at zero, is silent */
+ end = cur->second;
+ in_silence = true;
+ } else {
+ /* initial segment, starting at zero, is audible */
+ end = cur->first;
+ in_silence = false;
+ }
+
+ while (cur != res.end()) {
+
+ framecnt_t interval_duration;
+
+ interval_duration = end - start;
+
+ if (in_silence) {
+
+ max_silence = max (max_silence, interval_duration);
+ min_silence = min (min_silence, interval_duration);
+ } else {
+
+ max_audible = max (max_audible, interval_duration);
+ min_audible = min (min_audible, interval_duration);
+ }
+
+ start = end;
+ ++cur;
+ end = cur->first;
+ in_silence = !in_silence;
+ }
+}
+
+nframes_t
+StripSilenceDialog::minimum_length () const
+{
+ return _minimum_length.current_duration (_waves.front()->region->position());
+}
+
+nframes_t
+StripSilenceDialog::fade_length () const
+{
+ return _minimum_length.current_duration (_waves.front()->region->position());
+}
+
+StripSilenceDialog::Wave::Wave (Group* g, boost::shared_ptr<AudioRegion> r)
+ : region (r), view (0), samples_per_unit (1)
+{
+ threshold_line = new ArdourCanvas::SimpleLine (*g);
+ threshold_line->property_color_rgba() = RGBA_TO_UINT (0, 0, 0, 128);
+}
+
+StripSilenceDialog::Wave::~Wave ()
+{
+ delete view;
+ delete threshold_line;
+ for (list<SimpleRect*>::iterator i = silence_rects.begin(); i != silence_rects.end(); ++i) {
+ delete *i;
+ }