diff options
Diffstat (limited to 'libs/ardour/audioregion.cc')
-rw-r--r-- | libs/ardour/audioregion.cc | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 822fe2cb72..20115ff944 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -66,12 +66,12 @@ void AudioRegion::init () { _scale_amplitude = 1.0; - valid_transients = false; set_default_fades (); set_default_envelope (); listen_to_my_curves (); + listen_to_my_sources (); } /* constructor for use by derived types only */ @@ -122,6 +122,7 @@ AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t len , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) { init (); + listen_to_my_sources (); } /** Create a new AudioRegion, that is part of an existing one */ @@ -172,9 +173,9 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t } _scale_amplitude = other->_scale_amplitude; - valid_transients = false; assert(_type == DataType::AUDIO); + listen_to_my_sources (); } AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) @@ -183,15 +184,14 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) { + assert(_type == DataType::AUDIO); _scale_amplitude = other->_scale_amplitude; - valid_transients = false; _envelope = other->_envelope; set_default_fades (); listen_to_my_curves (); - - assert(_type == DataType::AUDIO); + listen_to_my_sources (); } AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node) @@ -206,13 +206,13 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod } init (); - valid_transients = false; if (set_state (node)) { throw failed_constructor(); } assert(_type == DataType::AUDIO); + listen_to_my_sources (); } AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) @@ -228,6 +228,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) } assert(_type == DataType::AUDIO); + listen_to_my_sources (); } AudioRegion::~AudioRegion () @@ -235,10 +236,11 @@ AudioRegion::~AudioRegion () } void -AudioRegion::invalidate_transients () +AudioRegion::listen_to_my_sources () { - valid_transients = false; - _transients.clear (); + for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { + (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients)); + } } void @@ -1256,53 +1258,73 @@ AudioRegion::audio_source (uint32_t n) const return boost::dynamic_pointer_cast<AudioSource>(source(n)); } -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, bool force_new) +AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new) { - if (!playlist()) { + boost::shared_ptr<Playlist> pl = playlist(); + + if (!pl) { return -1; } - if (valid_transients && !force_new) { + if (_valid_transients && !force_new) { results = _transients; return 0; } - TransientDetector t (playlist()->session().frame_rate()); + SourceList::iterator s; + + for (s = _sources.begin() ; s != _sources.end(); ++s) { + if (!(*s)->has_been_analysed()) { + cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n"; + break; + } + } + + if (s == _sources.end()) { + /* all sources are analyzed, merge data from each one */ + + for (s = _sources.begin() ; s != _sources.end(); ++s) { + + /* find the set of transients within the bounds of this region */ + + AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(), + (*s)->transients.end(), + _start); + + AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(), + (*s)->transients.end(), + _start + _length); + + /* and add them */ + + results.insert (results.end(), low, high); + } + + TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0); + + /* translate all transients to current position */ + + for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) { + (*x) -= _start; + (*x) += _position; + } + + _transients = results; + _valid_transients = true; + + return 0; + } + + TransientDetector t (pl->session().frame_rate()); bool existing_results = !results.empty(); _transients.clear (); - valid_transients = false; + _valid_transients = false; for (uint32_t i = 0; i < n_channels(); ++i) { - vector<nframes64_t> these_results; + AnalysisFeatureList these_results; t.reset (); @@ -1312,7 +1334,7 @@ AudioRegion::get_transients (vector<nframes64_t>& results, bool force_new) /* translate all transients to give absolute position */ - for (vector<nframes64_t>::iterator i = these_results.begin(); i != these_results.end(); ++i) { + for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) { (*i) += _position; } @@ -1329,20 +1351,19 @@ AudioRegion::get_transients (vector<nframes64_t>& results, bool force_new) */ results.insert (results.end(), _transients.begin(), _transients.end()); - cleanup_transients (results); + TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0); } /* make sure ours are clean too */ - cleanup_transients (_transients); + TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0); } - valid_transients = true; + _valid_transients = true; return 0; } - 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) |