add silence-stripping fade constraints

Ensure that non-silent regions are at least
as long as the selected fade-duration.
This commit is contained in:
Robin Gareus 2015-09-20 01:28:15 +02:00
parent 21c1d0f832
commit 861d6f81a3
3 changed files with 55 additions and 9 deletions

View file

@ -172,7 +172,7 @@ class LIBARDOUR_API AudioRegion : public Region
int update_transient (framepos_t old_position, framepos_t new_position); int update_transient (framepos_t old_position, framepos_t new_position);
int adjust_transients (frameoffset_t delta); 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: private:
friend class RegionFactory; friend class RegionFactory;

View file

@ -1799,7 +1799,7 @@ in this and future transient-detection operations.\n\
*/ */
AudioIntervalResult 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; framecnt_t const block_size = 64 * 1024;
boost::scoped_array<Sample> loudest (new Sample[block_size]); 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; bool in_silence = false;
frameoffset_t silence_start = 0; 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) { while (pos < end && !itt.cancel) {
/* fill `loudest' with the loudest absolute sample at each instant, across all channels */ /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
@ -1831,24 +1834,61 @@ AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadI
if (silence && !in_silence) { if (silence && !in_silence) {
/* non-silence to silence */ /* non-silence to silence */
in_silence = true; 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;
}
} else if (!silence && in_silence) { } else if (!silence && in_silence) {
/* silence to non-silence */ /* silence to non-silence */
in_silence = false; in_silence = false;
hold_off = 0;
if (pos + i - 1 - silence_start >= min_length) { 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; pos += block_size;
itt.progress = (end-pos)/(double)_length; 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 */ /* 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)); silent_periods.push_back (std::make_pair (silence_start, end));
} }
}
itt.done = true; itt.done = true;

View 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)); framecnt_t const f = std::min (_fade_length, (i->second - i->first));
if (f > 0) {
copy->set_fade_in_active (true); copy->set_fade_in_active (true);
copy->set_fade_out_active (true);
copy->set_fade_in (FadeLinear, f); copy->set_fade_in (FadeLinear, f);
copy->set_fade_out (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); results.push_back (copy);
if (progress && (n <= N)) { if (progress && (n <= N)) {