add silence-stripping fade constraints
authorRobin Gareus <robin@gareus.org>
Sat, 19 Sep 2015 23:28:15 +0000 (01:28 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 19 Sep 2015 23:28:15 +0000 (01:28 +0200)
Ensure that non-silent regions are at least
as long as the selected fade-duration.

libs/ardour/ardour/audioregion.h
libs/ardour/audioregion.cc
libs/ardour/strip_silence.cc

index 086544f3aa33ab46a30e927370cfe9839bfc58c8..9172021e972402f16fdbec3581918a96e49e9835 100644 (file)
@@ -172,7 +172,7 @@ class LIBARDOUR_API AudioRegion : public Region
        int update_transient (framepos_t old_position, framepos_t new_position);
        int adjust_transients (frameoffset_t delta);
 
-       AudioIntervalResult find_silence (Sample, framecnt_t, InterThreadInfo&) const;
+       AudioIntervalResult find_silence (Sample, framecnt_t, framecnt_t, InterThreadInfo&) const;
 
   private:
        friend class RegionFactory;
index a3535565dd085def2d9287f444dc3f7bc905fa6b..9a9459f9b90435b36e44d6df7bd11e993423c811 100644 (file)
@@ -1799,7 +1799,7 @@ in this and future transient-detection operations.\n\
  */
 
 AudioIntervalResult
-AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
+AudioRegion::find_silence (Sample threshold, framecnt_t min_length, framecnt_t fade_length, InterThreadInfo& itt) const
 {
        framecnt_t const block_size = 64 * 1024;
        boost::scoped_array<Sample> loudest (new Sample[block_size]);
@@ -1812,7 +1812,10 @@ AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadI
 
        bool in_silence = false;
        frameoffset_t silence_start = 0;
+       frameoffset_t silence_end = 0;
 
+       framecnt_t continuous_signal = fade_length;
+       framecnt_t hold_off = 0;
        while (pos < end && !itt.cancel) {
 
                /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
@@ -1831,23 +1834,60 @@ AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadI
                        if (silence && !in_silence) {
                                /* non-silence to silence */
                                in_silence = true;
-                               silence_start = pos + i;
+                               /* process last queued silent part if any */
+                               if (hold_off > 0) {
+                                       assert (hold_off < fade_length);
+                                       silence_end -= hold_off;
+                                       if (silence_end - silence_start >= min_length) {
+                                               silent_periods.push_back (std::make_pair (silence_start, silence_end));
+                                       }
+                               }
+                               hold_off = 0;
+
+                               if (continuous_signal < fade_length) {
+                                       silence_start = pos + i + fade_length - continuous_signal;
+                               } else {
+                                       silence_start = pos + i;
+                               }
                        } else if (!silence && in_silence) {
                                /* silence to non-silence */
                                in_silence = false;
+                               hold_off = 0;
                                if (pos + i - 1 - silence_start >= min_length) {
-                                       silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
+                                       /* queue silence */
+                                       silence_end = pos + i - 1;
+                                       hold_off = 1;
+                               }
+                       }
+
+                       if (hold_off > 0) {
+                               assert (!in_silence);
+                               if (++hold_off >= fade_length) {
+                                       silent_periods.push_back (std::make_pair (silence_start, silence_end));
+                                       hold_off = 0;
                                }
                        }
+
+                       if (!silence) {
+                               ++continuous_signal;
+                       } else {
+                               continuous_signal = 0;
+                       }
                }
 
                pos += block_size;
                itt.progress = (end-pos)/(double)_length;
        }
 
-       if (in_silence && end - 1 - silence_start >= min_length) {
+       if (in_silence) {
                /* last block was silent, so finish off the last period */
-               silent_periods.push_back (std::make_pair (silence_start, end));
+               assert (hold_off == 0);
+               if (continuous_signal < fade_length) {
+                       silence_start += fade_length - continuous_signal;
+               }
+               if (end - 1 - silence_start >= min_length) {
+                       silent_periods.push_back (std::make_pair (silence_start, end));
+               }
        }
 
        itt.done = true;
index ff79371b966551bbc54fcd2dc1ce6751316e04f6..b0109d5989b83b171678b442ef1ef4ed1eb40459 100644 (file)
@@ -123,9 +123,15 @@ StripSilence::run (boost::shared_ptr<Region> r, Progress* progress)
 
                framecnt_t const f = std::min (_fade_length, (i->second - i->first));
 
-               copy->set_fade_in_active (true);
-               copy->set_fade_in (FadeLinear, f);
-               copy->set_fade_out (FadeLinear, f);
+               if (f > 0) {
+                       copy->set_fade_in_active (true);
+                       copy->set_fade_out_active (true);
+                       copy->set_fade_in (FadeLinear, f);
+                       copy->set_fade_out (FadeLinear, f);
+               } else {
+                       copy->set_fade_in_active (false);
+                       copy->set_fade_out_active (false);
+               }
                results.push_back (copy);
 
                if (progress && (n <= N)) {