X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudioregion.cc;h=855ff074ca2d6db7aa2bf5f368d04366538d90c8;hb=ffdf5ada616d285fafb58f45c2e3d37b212a328a;hp=659d638ad617c69f2217df38ce76dfd3d22c32a8;hpb=a61f25dfe9dcf1f29852d917779529d26e762ea5;p=ardour.git diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 659d638ad6..855ff074ca 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -38,7 +38,8 @@ #include #include #include -#include +#include +#include #include "i18n.h" #include @@ -64,7 +65,7 @@ AudioRegionState::AudioRegionState (string why) { } -AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t start, jack_nframes_t length) +AudioRegion::AudioRegion (boost::shared_ptr src, nframes_t start, nframes_t length) : Region (start, length, PBD::basename_nosuffix(src->name()), 0, Region::Flag(Region::DefaultFlags|Region::External)), _fade_in (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false), @@ -76,6 +77,11 @@ AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t sta master_sources.push_back (src); src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src)); + boost::shared_ptr afs = boost::dynamic_pointer_cast (src); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + _scale_amplitude = 1.0; set_default_fades (); @@ -86,7 +92,7 @@ AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t sta _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); } -AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags) +AudioRegion::AudioRegion (boost::shared_ptr src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) : Region (start, length, name, layer, flags), _fade_in (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false), @@ -98,6 +104,11 @@ AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t sta master_sources.push_back (src); src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src)); + boost::shared_ptr afs = boost::dynamic_pointer_cast (src); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + _scale_amplitude = 1.0; set_default_fades (); @@ -107,7 +118,7 @@ AudioRegion::AudioRegion (boost::shared_ptr src, jack_nframes_t sta _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); } -AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags) +AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) : Region (start, length, name, layer, flags), _fade_in (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false), @@ -119,6 +130,11 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t sources.push_back (*i); master_sources.push_back (*i); (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), (*i))); + + boost::shared_ptr afs = boost::dynamic_pointer_cast ((*i)); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } } _scale_amplitude = 1.0; @@ -131,7 +147,7 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t } -AudioRegion::AudioRegion (boost::shared_ptr other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags) +AudioRegion::AudioRegion (boost::shared_ptr other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : Region (other, offset, length, name, layer, flags), _fade_in (other->_fade_in), _fade_out (other->_fade_out), @@ -144,7 +160,17 @@ AudioRegion::AudioRegion (boost::shared_ptr other, jack_nfram for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) { sources.push_back (*i); (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i)); - unique_srcs.insert (*i); + + pair >::iterator,bool> result; + + result = unique_srcs.insert (*i); + + if (result.second) { + boost::shared_ptr afs = boost::dynamic_pointer_cast (*i); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + } } for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) { @@ -199,7 +225,16 @@ AudioRegion::AudioRegion (boost::shared_ptr other) for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) { sources.push_back (*i); (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i)); - unique_srcs.insert (*i); + pair >::iterator,bool> result; + + result = unique_srcs.insert (*i); + + if (result.second) { + boost::shared_ptr afs = boost::dynamic_pointer_cast (*i); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + } } for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) { @@ -218,8 +253,6 @@ AudioRegion::AudioRegion (boost::shared_ptr other) save_state ("initial state"); _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); - - /* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */ } AudioRegion::AudioRegion (boost::shared_ptr src, const XMLNode& node) @@ -232,6 +265,11 @@ AudioRegion::AudioRegion (boost::shared_ptr src, const XMLNode& nod master_sources.push_back (src); src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src)); + boost::shared_ptr afs = boost::dynamic_pointer_cast (src); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + set_default_fades (); if (set_state (node)) { @@ -254,7 +292,16 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) { sources.push_back (*i); (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i)); - unique_srcs.insert (*i); + pair >::iterator,bool> result; + + result = unique_srcs.insert (*i); + + if (result.second) { + boost::shared_ptr afs = boost::dynamic_pointer_cast (*i); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + } } for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) { @@ -364,8 +411,12 @@ AudioRegion::get_memento() const } bool -AudioRegion::verify_length (jack_nframes_t len) +AudioRegion::verify_length (nframes_t len) { + if (boost::dynamic_pointer_cast(source())) { + return true; + } + for (uint32_t n=0; n < sources.size(); ++n) { if (_start > sources[n]->length() - len) { return false; @@ -375,8 +426,12 @@ AudioRegion::verify_length (jack_nframes_t len) } bool -AudioRegion::verify_start_and_length (jack_nframes_t new_start, jack_nframes_t new_length) +AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t new_length) { + if (boost::dynamic_pointer_cast(source())) { + return true; + } + for (uint32_t n=0; n < sources.size(); ++n) { if (new_length > sources[n]->length() - new_start) { return false; @@ -385,8 +440,12 @@ AudioRegion::verify_start_and_length (jack_nframes_t new_start, jack_nframes_t n return true; } bool -AudioRegion::verify_start (jack_nframes_t pos) +AudioRegion::verify_start (nframes_t pos) { + if (boost::dynamic_pointer_cast(source())) { + return true; + } + for (uint32_t n=0; n < sources.size(); ++n) { if (pos > sources[n]->length() - _length) { return false; @@ -396,8 +455,12 @@ AudioRegion::verify_start (jack_nframes_t pos) } bool -AudioRegion::verify_start_mutable (jack_nframes_t& new_start) +AudioRegion::verify_start_mutable (nframes_t& new_start) { + if (boost::dynamic_pointer_cast(source())) { + return true; + } + for (uint32_t n=0; n < sources.size(); ++n) { if (new_start > sources[n]->length() - _length) { new_start = sources[n]->length() - _length; @@ -425,8 +488,8 @@ AudioRegion::set_envelope_active (bool yn) } } -jack_nframes_t -AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n, double samples_per_unit) const +nframes_t +AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const { if (chan_n >= sources.size()) { return 0; @@ -436,7 +499,7 @@ AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t of return 0; } else { if (_scale_amplitude != 1.0) { - for (jack_nframes_t n = 0; n < npeaks; ++n) { + for (nframes_t n = 0; n < npeaks; ++n) { buf[n].max *= _scale_amplitude; buf[n].min *= _scale_amplitude; } @@ -445,30 +508,30 @@ AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t of } } -jack_nframes_t -AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t position, - jack_nframes_t cnt, - uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const +nframes_t +AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, + nframes_t cnt, + uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const { return _read_at (sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames); } -jack_nframes_t -AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t position, - jack_nframes_t cnt, uint32_t chan_n) const +nframes_t +AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, + nframes_t cnt, uint32_t chan_n) const { return _read_at (master_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0); } -jack_nframes_t +nframes_t AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buffer, float *gain_buffer, - jack_nframes_t position, jack_nframes_t cnt, - uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const + nframes_t position, nframes_t cnt, + uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const { - jack_nframes_t internal_offset; - jack_nframes_t buf_offset; - jack_nframes_t to_read; - + nframes_t internal_offset; + nframes_t buf_offset; + nframes_t to_read; + /* precondition: caller has verified that we cover the desired section */ if (chan_n >= sources.size()) { @@ -487,7 +550,6 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff if (internal_offset >= _length) { return 0; /* read nothing */ } - if ((to_read = min (cnt, _length - internal_offset)) == 0) { return 0; /* read nothing */ @@ -516,19 +578,19 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff if (_flags & FadeIn) { - jack_nframes_t fade_in_length = (jack_nframes_t) _fade_in.back()->when; + nframes_t fade_in_length = (nframes_t) _fade_in.back()->when; /* see if this read is within the fade in */ if (internal_offset < fade_in_length) { - jack_nframes_t limit; + nframes_t limit; limit = min (to_read, fade_in_length - internal_offset); _fade_in.get_vector (internal_offset, internal_offset+limit, gain_buffer, limit); - for (jack_nframes_t n = 0; n < limit; ++n) { + for (nframes_t n = 0; n < limit; ++n) { mixdown_buffer[n] *= gain_buffer[n]; } } @@ -538,9 +600,6 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff if (_flags & FadeOut) { - - - /* see if some part of this read is within the fade out */ /* ................. >| REGION @@ -560,20 +619,20 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff */ - jack_nframes_t fade_out_length = (jack_nframes_t) _fade_out.back()->when; - jack_nframes_t fade_interval_start = max(internal_offset, _length-fade_out_length); - jack_nframes_t fade_interval_end = min(internal_offset + to_read, _length); + nframes_t fade_out_length = (nframes_t) _fade_out.back()->when; + nframes_t fade_interval_start = max(internal_offset, _length-fade_out_length); + nframes_t fade_interval_end = min(internal_offset + to_read, _length); if (fade_interval_end > fade_interval_start) { /* (part of the) the fade out is in this buffer */ - jack_nframes_t limit = fade_interval_end - fade_interval_start; - jack_nframes_t curve_offset = fade_interval_start - (_length-fade_out_length); - jack_nframes_t fade_offset = fade_interval_start - internal_offset; + nframes_t limit = fade_interval_end - fade_interval_start; + nframes_t curve_offset = fade_interval_start - (_length-fade_out_length); + nframes_t fade_offset = fade_interval_start - internal_offset; _fade_out.get_vector (curve_offset,curve_offset+limit, gain_buffer, limit); - for (jack_nframes_t n = 0, m = fade_offset; n < limit; ++n, ++m) { + for (nframes_t n = 0, m = fade_offset; n < limit; ++n, ++m) { mixdown_buffer[m] *= gain_buffer[n]; } } @@ -586,11 +645,11 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read); if (_scale_amplitude != 1.0f) { - for (jack_nframes_t n = 0; n < to_read; ++n) { + for (nframes_t n = 0; n < to_read; ++n) { mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude; } } else { - for (jack_nframes_t n = 0; n < to_read; ++n) { + for (nframes_t n = 0; n < to_read; ++n) { mixdown_buffer[n] *= gain_buffer[n]; } } @@ -605,7 +664,7 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff buf += buf_offset; - for (jack_nframes_t n = 0; n < to_read; ++n) { + for (nframes_t n = 0; n < to_read; ++n) { buf[n] += mixdown_buffer[n]; } } @@ -629,7 +688,7 @@ AudioRegion::state (bool full) for (uint32_t n=0; n < sources.size(); ++n) { snprintf (buf2, sizeof(buf2), "source-%d", n); - sources[n]->id().print (buf); + sources[n]->id().print (buf, sizeof (buf)); node.add_property (buf2, buf); } @@ -759,17 +818,17 @@ AudioRegion::set_state (const XMLNode& node) void AudioRegion::set_fade_in_shape (FadeShape shape) { - set_fade_in (shape, (jack_nframes_t) _fade_in.back()->when); + set_fade_in (shape, (nframes_t) _fade_in.back()->when); } void AudioRegion::set_fade_out_shape (FadeShape shape) { - set_fade_out (shape, (jack_nframes_t) _fade_out.back()->when); + set_fade_out (shape, (nframes_t) _fade_out.back()->when); } void -AudioRegion::set_fade_in (FadeShape shape, jack_nframes_t len) +AudioRegion::set_fade_in (FadeShape shape, nframes_t len) { _fade_in.freeze (); _fade_in.clear (); @@ -833,7 +892,7 @@ AudioRegion::set_fade_in (FadeShape shape, jack_nframes_t len) } void -AudioRegion::set_fade_out (FadeShape shape, jack_nframes_t len) +AudioRegion::set_fade_out (FadeShape shape, nframes_t len) { _fade_out.freeze (); _fade_out.clear (); @@ -895,7 +954,7 @@ AudioRegion::set_fade_out (FadeShape shape, jack_nframes_t len) } void -AudioRegion::set_fade_in_length (jack_nframes_t len) +AudioRegion::set_fade_in_length (nframes_t len) { bool changed = _fade_in.extend_to (len); @@ -913,7 +972,7 @@ AudioRegion::set_fade_in_length (jack_nframes_t len) } void -AudioRegion::set_fade_out_length (jack_nframes_t len) +AudioRegion::set_fade_out_length (nframes_t len) { bool changed = _fade_out.extend_to (len); @@ -1111,8 +1170,8 @@ AudioRegion::apply (AudioFilter& filter) int AudioRegion::exportme (Session& session, AudioExportSpecification& spec) { - const jack_nframes_t blocksize = 4096; - jack_nframes_t to_read; + const nframes_t blocksize = 4096; + nframes_t to_read; int status = -1; spec.channels = sources.size(); @@ -1147,7 +1206,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec) goto out; } - for (jack_nframes_t x = 0; x < to_read; ++x) { + for (nframes_t x = 0; x < to_read; ++x) { spec.dataF[chan+(x*spec.channels)] = buf[x]; } } @@ -1203,11 +1262,11 @@ AudioRegion::set_scale_amplitude (gain_t g) void AudioRegion::normalize_to (float target_dB) { - const jack_nframes_t blocksize = 64 * 1024; + const nframes_t blocksize = 64 * 1024; Sample buf[blocksize]; - jack_nframes_t fpos; - jack_nframes_t fend; - jack_nframes_t to_read; + nframes_t fpos; + nframes_t fend; + nframes_t to_read; double maxamp = 0; gain_t target = dB_to_coefficient (target_dB); @@ -1326,11 +1385,22 @@ AudioRegion::speed_mismatch (float sr) const return fsr != sr; } +void +AudioRegion::source_offset_changed () +{ + if (boost::dynamic_pointer_cast(sources.front())) { + set_start (source()->natural_position(), this); + set_position (source()->natural_position(), this); + } else { + set_position (source()->natural_position() + start(), this); + } +} + 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) { - return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (jack_nframes_t) npeaks, (jack_nframes_t) start, (jack_nframes_t) cnt, n_chan,samples_per_unit); + return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit); } uint32_t region_length_from_c (void *arg)