diff options
author | Carl Hetherington <carl@carlh.net> | 2009-04-29 17:01:14 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2009-04-29 17:01:14 +0000 |
commit | 459c43951238fd771231f840733468b84079dcdc (patch) | |
tree | d04b98a7be7f6028bbce64efe151d6486c3376b2 /libs/ardour | |
parent | 7eba373a0f9e48f8f68ac613021748e08f42ec4d (diff) |
First cut of option to strip silence from audio regions, as per mantis #1623
git-svn-id: svn://localhost/ardour2/branches/3.0@5010 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/SConscript | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/audioregion.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/crossfade.h | 2 | ||||
-rw-r--r-- | libs/ardour/audioregion.cc | 71 | ||||
-rw-r--r-- | libs/ardour/crossfade.cc | 2 | ||||
-rw-r--r-- | libs/ardour/region.cc | 1 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 |
7 files changed, 75 insertions, 6 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index d30c276840..27cffdff9d 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -159,6 +159,7 @@ sndfileimportable.cc sndfilesource.cc source.cc source_factory.cc +strip_silence.cc svn_revision.cc tape_file_matcher.cc template_utils.cc diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 917578191f..b2e2aa3eef 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -106,7 +106,7 @@ class AudioRegion : public Region virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf, sframes_t position, nframes_t cnt, uint32_t chan_n=0) const; - virtual nframes_t read_raw_internal (Sample*, sframes_t, nframes_t) const; + virtual nframes_t read_raw_internal (Sample*, sframes_t, nframes_t, int channel) const; XMLNode& state (bool); int set_state (const XMLNode&); @@ -162,6 +162,7 @@ class AudioRegion : public Region void resume_fade_out (); int get_transients (AnalysisFeatureList&, bool force_new = false); + std::list<std::pair<nframes_t, nframes_t> > find_silence (Sample, nframes_t) const; private: friend class RegionFactory; diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index bd3ee914f9..4afa38126c 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -170,7 +170,7 @@ class Crossfade : public ARDOUR::AudioRegion bool update (); protected: - nframes_t read_raw_internal (Sample*, sframes_t, nframes_t) const; + nframes_t read_raw_internal (Sample*, sframes_t, nframes_t, int) const; }; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 085296281c..b3fd239c59 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -1062,9 +1062,9 @@ AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<Reg } nframes_t -AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt) const +AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt, int channel) const { - return audio_source()->read (buf, pos, cnt); + return audio_source()->read (buf, pos, cnt, channel); } int @@ -1184,7 +1184,7 @@ AudioRegion::normalize_to (float target_dB) /* read it in */ - if (read_raw_internal (buf, fpos, to_read) != to_read) { + if (read_raw_internal (buf, fpos, to_read, 0) != to_read) { return; } @@ -1438,6 +1438,71 @@ then quit ardour and restart.")); return 0; } +/** Find areas of `silence' within a region. + * + * @param threshold Threshold below which signal is considered silence (as a sample value) + * @param min_length Minimum length of silent period to be reported. + * @return Silent periods; first of pair is the offset within the region, second is the length of the period + */ + +std::list<std::pair<nframes_t, nframes_t> > +AudioRegion::find_silence (Sample threshold, nframes_t min_length) const +{ + nframes_t const block_size = 64 * 1024; + Sample loudest[block_size]; + Sample buf[block_size]; + + nframes_t pos = _start; + nframes_t const end = _start + _length - 1; + + std::list<std::pair<nframes_t, nframes_t> > silent_periods; + + bool in_silence = false; + nframes_t silence_start = 0; + bool silence; + + while (pos < end) { + + nframes_t const to_read = min (end - pos, block_size); + + /* fill `loudest' with the loudest absolute sample at each instant, across all channels */ + memset (loudest, 0, sizeof (Sample) * block_size); + for (uint32_t n = 0; n < n_channels(); ++n) { + + read_raw_internal (buf, pos, block_size, n); + for (nframes_t i = 0; i < block_size; ++i) { + loudest[i] = max (loudest[i], abs (buf[i])); + } + } + + /* now look for silence */ + for (nframes_t i = 0; i < block_size; ++i) { + silence = abs (loudest[i]) < threshold; + if (silence && !in_silence) { + /* non-silence to silence */ + in_silence = true; + silence_start = pos + i; + } else if (!silence && in_silence) { + /* silence to non-silence */ + in_silence = false; + if (pos + i - 1 - silence_start >= min_length) { + silent_periods.push_back (std::make_pair (silence_start, pos + i - 1)); + } + } + } + + pos += block_size; + } + + if (in_silence && end - 1 - silence_start >= min_length) { + /* last block was silent, so finish off the last period */ + silent_periods.push_back (std::make_pair (silence_start, end)); + } + + return silent_periods; +} + + extern "C" { int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit) diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 8aad53765a..c258a9bf73 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -271,7 +271,7 @@ Crossfade::initialize () } nframes_t -Crossfade::read_raw_internal (Sample* buf, sframes_t start, nframes_t cnt) const +Crossfade::read_raw_internal (Sample* buf, sframes_t start, nframes_t cnt, int channel) const { // FIXME: Why is this disabled? #if 0 diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index dcca313c79..a90a2b244d 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -1638,3 +1638,4 @@ Region::invalidate_transients () _transients.clear (); } + diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 342ca79a0a..b087e194c2 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -198,6 +198,7 @@ def build(bld): sndfilesource.cc source.cc source_factory.cc + strip_silence.cc svn_revision.cc tape_file_matcher.cc template_utils.cc |