From 70bed9d6a01279fa9d9fc03738e591f0bedd3362 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 20 Sep 2015 19:40:32 +0200 Subject: silence detection: include fades. Fades must be outside of regions above threshold in order to properly split drum-hits or fast transients in general. --- libs/ardour/audioregion.cc | 73 ++++++++++++++------------------------------ libs/ardour/strip_silence.cc | 2 +- 2 files changed, 24 insertions(+), 51 deletions(-) diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 9a9459f9b9..66d46cd837 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -1805,88 +1805,61 @@ AudioRegion::find_silence (Sample threshold, framecnt_t min_length, framecnt_t f boost::scoped_array loudest (new Sample[block_size]); boost::scoped_array buf (new Sample[block_size]); + assert (fade_length >= 0); + assert (min_length > 0); + framepos_t pos = _start; - framepos_t const end = _start + _length - 1; + framepos_t const end = _start + _length; AudioIntervalResult silent_periods; - bool in_silence = false; - frameoffset_t silence_start = 0; - frameoffset_t silence_end = 0; + bool in_silence = true; + frameoffset_t silence_start = _start; - framecnt_t continuous_signal = fade_length; - framecnt_t hold_off = 0; while (pos < end && !itt.cancel) { + framecnt_t cur_samples = 0; /* fill `loudest' with the loudest absolute sample at each instant, across all channels */ memset (loudest.get(), 0, sizeof (Sample) * block_size); for (uint32_t n = 0; n < n_channels(); ++n) { - read_raw_internal (buf.get(), pos, block_size, n); - for (framecnt_t i = 0; i < block_size; ++i) { + cur_samples = read_raw_internal (buf.get(), pos, block_size, n); + for (framecnt_t i = 0; i < cur_samples; ++i) { loudest[i] = max (loudest[i], abs (buf[i])); } } /* now look for silence */ - for (framecnt_t i = 0; i < block_size; ++i) { + for (framecnt_t i = 0; i < cur_samples; ++i) { bool const silence = abs (loudest[i]) < threshold; if (silence && !in_silence) { /* non-silence to silence */ in_silence = true; - /* 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; - } + silence_start = pos + i + fade_length; } else if (!silence && in_silence) { /* silence to non-silence */ in_silence = false; - hold_off = 0; - if (pos + i - 1 - silence_start >= min_length) { - /* queue silence */ - silence_end = pos + i - 1; - hold_off = 1; - } - } + frameoffset_t silence_end = pos + i - 1 - fade_length; - if (hold_off > 0) { - assert (!in_silence); - if (++hold_off >= fade_length) { + if (silence_end - silence_start >= min_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; + pos += cur_samples; + itt.progress = (end - pos) / (double)_length; + + if (cur_samples == 0) { + assert (pos >= end); + break; + } } - if (in_silence) { + if (in_silence && !itt.cancel) { /* last block was silent, so finish off the last period */ - 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)); + if (end - 1 - silence_start >= min_length + fade_length) { + silent_periods.push_back (std::make_pair (silence_start, end - 1)); } } diff --git a/libs/ardour/strip_silence.cc b/libs/ardour/strip_silence.cc index b0109d5989..3141f422a8 100644 --- a/libs/ardour/strip_silence.cc +++ b/libs/ardour/strip_silence.cc @@ -121,7 +121,7 @@ StripSilence::run (boost::shared_ptr r, Progress* progress) copy->set_name (RegionFactory::new_region_name (region->name ())); - framecnt_t const f = std::min (_fade_length, (i->second - i->first)); + framecnt_t const f = std::min (_fade_length, (i->second - i->first) / 2); if (f > 0) { copy->set_fade_in_active (true); -- cgit v1.2.3