diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-01-26 02:57:10 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-01-26 02:57:10 +0000 |
commit | 1e51f099fd7baef957204d46bee302908d65de6b (patch) | |
tree | efc8fbf95a139ee90508ad6f6ea17ab652457c5a /libs | |
parent | 315dd3d7705d314b935a7a35007347a41e0f9bfd (diff) |
first pass attempt at tab-to-transient (to be improved)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2970 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/audioregion.h | 7 | ||||
-rw-r--r-- | libs/ardour/audioregion.cc | 89 |
2 files changed, 70 insertions, 26 deletions
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 5bc59a715a..ba14d05afe 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -148,7 +148,7 @@ class AudioRegion : public Region void set_playlist (boost::weak_ptr<Playlist>); - int get_transients (std::vector<nframes64_t>&); + int get_transients (std::vector<nframes64_t>&, bool force_new = false); private: friend class RegionFactory; @@ -207,6 +207,11 @@ class AudioRegion : public Region protected: int set_live_state (const XMLNode&, Change&, bool send); + + std::vector<nframes64_t> _transients; + bool valid_transients; + void invalidate_transients (); + void cleanup_transients (std::vector<nframes64_t>&); }; } /* namespace ARDOUR */ diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 01728a8c01..fd39e05636 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -80,6 +80,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n } _scale_amplitude = 1.0; + valid_transients = false; set_default_fades (); set_default_envelope (); @@ -105,6 +106,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n } _scale_amplitude = 1.0; + valid_transients = false; set_default_fades (); set_default_envelope (); @@ -132,6 +134,7 @@ AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t len } _scale_amplitude = 1.0; + valid_transients = false; set_default_fades (); set_default_envelope (); @@ -200,6 +203,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t } _scale_amplitude = other->_scale_amplitude; + valid_transients = false; listen_to_my_curves (); } @@ -237,6 +241,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) } _scale_amplitude = other->_scale_amplitude; + valid_transients = false; _envelope = other->_envelope; _fade_in_disabled = 0; @@ -261,6 +266,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod } set_default_fades (); + valid_transients = false; if (set_state (node)) { throw failed_constructor(); @@ -301,6 +307,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) set_default_fades (); _scale_amplitude = 1.0; + valid_transients = false; if (set_state (node)) { throw failed_constructor(); @@ -324,6 +331,13 @@ AudioRegion::~AudioRegion () } void +AudioRegion::invalidate_transients () +{ + valid_transients = false; + _transients.clear (); +} + +void AudioRegion::listen_to_my_curves () { _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); @@ -1503,16 +1517,50 @@ AudioRegion::set_playlist (boost::weak_ptr<Playlist> wpl) } } +void +AudioRegion::cleanup_transients (vector<nframes64_t>& t) +{ + sort (t.begin(), t.end()); + + /* remove duplicates or other things that are too close */ + + vector<nframes64_t>::iterator i = t.begin(); + nframes64_t curr = (*i); + + /* XXX force a 3msec gap - use a config variable */ + + nframes64_t gap_frames = (nframes64_t) floor (3.0 * (playlist()->session().frame_rate() / 1000.0)); + + ++i; + + while (i != t.end()) { + if (((*i) == curr) || (((*i) - curr) < gap_frames)) { + i = t.erase (i); + } else { + ++i; + curr = *i; + } + } +} + int -AudioRegion::get_transients (vector<nframes64_t>& results) +AudioRegion::get_transients (vector<nframes64_t>& results, bool force_new) { if (!playlist()) { return -1; } + if (valid_transients && !force_new) { + results = _transients; + return 0; + } + TransientDetector t (playlist()->session().frame_rate()); bool existing_results = !results.empty(); + _transients.clear (); + valid_transients = false; + for (uint32_t i = 0; i < n_channels(); ++i) { vector<nframes64_t> these_results; @@ -1531,36 +1579,27 @@ AudioRegion::get_transients (vector<nframes64_t>& results) /* merge */ - results.insert (results.end(), these_results.begin(), these_results.end()); + _transients.insert (_transients.end(), these_results.begin(), these_results.end()); } - - if (!results.empty() && (existing_results || n_channels() > 1)) { - - /* now resort to bring transients from different channels together */ - - sort (results.begin(), results.end()); - - /* remove duplicates or other things that are too close */ - - vector<nframes64_t>::iterator i = results.begin(); - nframes64_t curr = (*i); - - /* XXX force a 3msec gap - use a config variable */ + + if (!results.empty()) { + if (existing_results) { + + /* merge our transients into the existing ones, then clean up + those. + */ - nframes64_t gap_frames = (nframes64_t) floor (3.0 * (playlist()->session().frame_rate() / 1000.0)); + results.insert (results.end(), _transients.begin(), _transients.end()); + cleanup_transients (results); + } - ++i; + /* make sure ours are clean too */ - while (i != results.end()) { - if (((*i) == curr) || (((*i) - curr) < gap_frames)) { - i = results.erase (i); - } else { - ++i; - curr = *i; - } - } + cleanup_transients (_transients); } + valid_transients = true; + return 0; } |