mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-29 09:57:44 +01:00
new region constructor for use by audiofilters (almost does a pure copy of the region, but sets start & sync_position appropriately, and uses new sources); fix up reverse bugs introduced in the last 36hrs; fix up setting of sync_position after split and so forth
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4140 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
7324e4cbe7
commit
a4d46fb4ef
9 changed files with 200 additions and 44 deletions
|
|
@ -169,6 +169,7 @@ class AudioRegion : public Region
|
|||
AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
|
||||
AudioRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
|
||||
AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
|
||||
AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
|
||||
AudioRegion (boost::shared_ptr<const AudioRegion>);
|
||||
AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
|
||||
AudioRegion (SourceList &, const XMLNode&);
|
||||
|
|
|
|||
|
|
@ -110,8 +110,9 @@ class Region : public PBD::StatefulDestructible, public Readable, public boost::
|
|||
|
||||
nframes_t sync_offset(int& dir) const;
|
||||
nframes_t sync_position() const;
|
||||
nframes_t sync_point () const;
|
||||
|
||||
nframes_t adjust_to_sync (nframes_t);
|
||||
nframes_t adjust_to_sync (nframes_t) const;
|
||||
|
||||
/* first_frame() is an alias; last_frame() just hides some math */
|
||||
|
||||
|
|
@ -212,10 +213,13 @@ class Region : public PBD::StatefulDestructible, public Readable, public boost::
|
|||
Region (nframes_t start, nframes_t length,
|
||||
const string& name, layer_t = 0, Flag flags = DefaultFlags);
|
||||
Region (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
|
||||
Region (boost::shared_ptr<const Region>, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
|
||||
Region (boost::shared_ptr<const Region>);
|
||||
Region (const XMLNode&);
|
||||
|
||||
protected:
|
||||
void copy_stuff (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t, Flag flags);
|
||||
|
||||
XMLNode& get_short_state (); /* used only by Session */
|
||||
|
||||
void send_change (Change);
|
||||
|
|
|
|||
|
|
@ -49,11 +49,12 @@ class RegionFactory {
|
|||
*/
|
||||
|
||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start,
|
||||
nframes_t length, std::string name,
|
||||
nframes_t length, const std::string& name,
|
||||
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
|
||||
static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, nframes_t start,
|
||||
nframes_t length, std::string name,
|
||||
nframes_t length, const std::string& name,
|
||||
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
|
||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, const SourceList&, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
|
||||
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
|
||||
static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
|
||||
static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
|
||||
|
|
|
|||
|
|
@ -113,6 +113,24 @@ AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs, s
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* make a new whole-file region that copies almost everything from the old one, but
|
||||
uses the new sources (and new length and name)
|
||||
*/
|
||||
|
||||
boost::shared_ptr<AudioRegion> ar;
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(nsrcs.front());
|
||||
|
||||
string whole_file_region_name = region_name_from_path (afs->path(), true);
|
||||
|
||||
ar = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create
|
||||
(nsrcs, 0, nsrcs.front()->length(), whole_file_region_name, 0,
|
||||
Region::Flag (Region::WholeFile|Region::DefaultFlags)));
|
||||
|
||||
/* now make a copy of the region that copies almost everything from the old one, but
|
||||
uses the new sources (and new length and name)
|
||||
*/
|
||||
|
||||
/* create a new region */
|
||||
|
||||
if (region_name.empty()) {
|
||||
|
|
@ -121,13 +139,14 @@ AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs, s
|
|||
|
||||
results.clear ();
|
||||
|
||||
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (
|
||||
RegionFactory::create (nsrcs, 0, nsrcs.front()->length(), region_name, 0,
|
||||
Region::Flag (Region::WholeFile|Region::DefaultFlags)));
|
||||
ar = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create
|
||||
(region, nsrcs, region_name, 0, region->flags()));
|
||||
|
||||
/* reset relevant stuff */
|
||||
/* if we changed the length, fix up the envelope */
|
||||
|
||||
ar->copy_settings (region);
|
||||
if (region->length() != ar->length()) {
|
||||
ar->envelope().extend_to (ar->length());
|
||||
}
|
||||
|
||||
results.push_back (ar);
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,38 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
|
|||
listen_to_my_sources ();
|
||||
}
|
||||
|
||||
AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs,
|
||||
nframes_t length, const string& name, layer_t layer, Flag flags)
|
||||
: Region (other, length, name, layer, flags),
|
||||
_fade_in (other->_fade_in),
|
||||
_fade_out (other->_fade_out),
|
||||
_envelope (other->_envelope)
|
||||
|
||||
{
|
||||
/* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
|
||||
|
||||
set<boost::shared_ptr<AudioSource> > unique_srcs;
|
||||
|
||||
for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
|
||||
sources.push_back (*i);
|
||||
master_sources.push_back (*i);
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
|
||||
if (afs) {
|
||||
afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
|
||||
}
|
||||
}
|
||||
|
||||
_scale_amplitude = other->_scale_amplitude;
|
||||
|
||||
_fade_in_disabled = 0;
|
||||
_fade_out_disabled = 0;
|
||||
|
||||
listen_to_my_curves ();
|
||||
listen_to_my_sources ();
|
||||
}
|
||||
|
||||
AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
|
||||
: Region (node),
|
||||
_fade_in (0.0, 2.0, 1.0, false),
|
||||
|
|
@ -349,22 +381,6 @@ AudioRegion::listen_to_my_curves ()
|
|||
_fade_out.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegion::copy_settings (boost::shared_ptr<const AudioRegion> other)
|
||||
{
|
||||
_fade_in = other->_fade_in;
|
||||
_fade_out = other->_fade_out;
|
||||
_envelope = other->_envelope;
|
||||
_flags = other->_flags;
|
||||
_scale_amplitude = other->_scale_amplitude;
|
||||
_fade_in_disabled = other->_fade_in_disabled;
|
||||
_fade_out_disabled = other->_fade_out_disabled;
|
||||
|
||||
if (_length != other->length()) {
|
||||
_envelope.extend_to (_length);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegion::verify_length (nframes_t& len)
|
||||
{
|
||||
|
|
@ -475,25 +491,25 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra
|
|||
}
|
||||
|
||||
nframes64_t
|
||||
AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
|
||||
AudioRegion::read (Sample* buf, nframes64_t timeline_position, nframes64_t cnt, int channel) const
|
||||
{
|
||||
/* raw read, no fades, no gain, nada */
|
||||
return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, ReadOps (0));
|
||||
return _read_at (sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
|
||||
}
|
||||
|
||||
nframes64_t
|
||||
AudioRegion::read_with_ops (Sample* buf, nframes64_t position, nframes64_t cnt, int channel, ReadOps rops) const
|
||||
AudioRegion::read_with_ops (Sample* buf, nframes64_t file_position, nframes64_t cnt, int channel, ReadOps rops) const
|
||||
{
|
||||
return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, rops);
|
||||
return _read_at (sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
|
||||
}
|
||||
|
||||
nframes_t
|
||||
AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
|
||||
AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t file_position,
|
||||
nframes_t cnt,
|
||||
uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
|
||||
{
|
||||
/* regular diskstream/butler read complete with fades etc */
|
||||
return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
|
||||
return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
|
||||
}
|
||||
|
||||
nframes_t
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include <ardour/session.h>
|
||||
#include <ardour/tempo.h>
|
||||
#include <ardour/region_factory.h>
|
||||
#include <ardour/profile.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -82,19 +83,100 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
|
|||
{
|
||||
/* create a new Region from part of an existing one */
|
||||
|
||||
_start = other->_start + offset;
|
||||
|
||||
copy_stuff (other, offset, length, name, layer, flags);
|
||||
|
||||
/* if the other region had a distinct sync point
|
||||
set, then continue to use it as best we can.
|
||||
otherwise, reset sync point back to start.
|
||||
*/
|
||||
|
||||
if (other->flags() & SyncMarked) {
|
||||
if (other->_sync_position < _start) {
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
} else {
|
||||
_sync_position = other->_sync_position;
|
||||
}
|
||||
} else {
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
}
|
||||
|
||||
if (Profile->get_sae()) {
|
||||
/* reset sync point to start if its ended up
|
||||
outside region bounds.
|
||||
*/
|
||||
|
||||
if (_sync_position < _start || _sync_position >= _start + _length) {
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Region::Region (boost::shared_ptr<const Region> other, nframes_t length, const string& name, layer_t layer, Flag flags)
|
||||
{
|
||||
/* create a new Region exactly like another but starting at 0 in its sources */
|
||||
|
||||
_start = 0;
|
||||
copy_stuff (other, 0, length, name, layer, flags);
|
||||
|
||||
/* sync pos is relative to start of file. our start-in-file is now zero,
|
||||
so set our sync position to whatever the the difference between
|
||||
_start and _sync_pos was in the other region.
|
||||
|
||||
result is that our new sync pos points to the same point in our source(s)
|
||||
as the sync in the other region did in its source(s).
|
||||
|
||||
since we start at zero in our source(s), it is not possible to use a sync point that
|
||||
is before the start. reset it to _start if that was true in the other region.
|
||||
*/
|
||||
|
||||
if (other->flags() & SyncMarked) {
|
||||
if (other->_start < other->_sync_position) {
|
||||
/* sync pos was after the start point of the other region */
|
||||
_sync_position = other->_sync_position - other->_start;
|
||||
} else {
|
||||
/* sync pos was before the start point of the other region. not possible here. */
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
}
|
||||
} else {
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
}
|
||||
|
||||
if (Profile->get_sae()) {
|
||||
/* reset sync point to start if its ended up
|
||||
outside region bounds.
|
||||
*/
|
||||
|
||||
if (_sync_position < _start || _sync_position >= _start + _length) {
|
||||
_flags = Flag (_flags & ~SyncMarked);
|
||||
_sync_position = _start;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset a couple of things that copy_stuff() gets wrong in this particular case */
|
||||
|
||||
_positional_lock_style = other->_positional_lock_style;
|
||||
_first_edit = other->_first_edit;
|
||||
}
|
||||
|
||||
void
|
||||
Region::copy_stuff (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
|
||||
{
|
||||
_frozen = 0;
|
||||
pending_changed = Change (0);
|
||||
_read_data_count = 0;
|
||||
valid_transients = false;
|
||||
|
||||
_start = other->_start + offset;
|
||||
if (other->_sync_position < offset) {
|
||||
_sync_position = other->_sync_position;
|
||||
} else {
|
||||
_sync_position = _start;
|
||||
}
|
||||
_length = length;
|
||||
_last_length = length;
|
||||
_sync_position = other->_sync_position;
|
||||
_ancestral_start = other->_ancestral_start;
|
||||
_ancestral_length = other->_ancestral_length;
|
||||
_stretch = other->_stretch;
|
||||
|
|
@ -765,7 +847,7 @@ Region::sync_offset (int& dir) const
|
|||
}
|
||||
|
||||
nframes_t
|
||||
Region::adjust_to_sync (nframes_t pos)
|
||||
Region::adjust_to_sync (nframes_t pos) const
|
||||
{
|
||||
int sync_dir;
|
||||
nframes_t offset = sync_offset (sync_dir);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ sigc::signal<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion;
|
|||
|
||||
boost::shared_ptr<Region>
|
||||
RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start,
|
||||
nframes_t length, std::string name,
|
||||
nframes_t length, const std::string& name,
|
||||
layer_t layer, Region::Flag flags, bool announce)
|
||||
{
|
||||
boost::shared_ptr<const AudioRegion> other;
|
||||
|
|
@ -75,12 +75,39 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
|
|||
|
||||
boost::shared_ptr<Region>
|
||||
RegionFactory::create (boost::shared_ptr<AudioRegion> region, nframes_t start,
|
||||
nframes_t length, std::string name,
|
||||
nframes_t length, const std::string& name,
|
||||
layer_t layer, Region::Flag flags, bool announce)
|
||||
{
|
||||
return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region>
|
||||
RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
|
||||
const std::string& name, layer_t layer, Region::Flag flags, bool announce)
|
||||
|
||||
{
|
||||
boost::shared_ptr<const AudioRegion> other;
|
||||
|
||||
/* used by AudioFilter when constructing a new region that is intended to have nearly
|
||||
identical settings to an original, but using different sources.
|
||||
*/
|
||||
|
||||
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
|
||||
AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(), name, layer, flags);
|
||||
boost::shared_ptr<AudioRegion> arp (ar);
|
||||
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
|
||||
if (announce) {
|
||||
CheckNewRegion (ret);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
fatal << _("programming error: RegionFactory::create() called with unknown Region type")
|
||||
<< endmsg;
|
||||
/*NOTREACHED*/
|
||||
return boost::shared_ptr<Region>();
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region>
|
||||
RegionFactory::create (Session& session, XMLNode& node, bool yn)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
|
|||
}
|
||||
|
||||
fpos = max (fstart, (fstart + region->length() - blocksize));
|
||||
|
||||
buf = new Sample[blocksize];
|
||||
to_read = blocksize;
|
||||
|
||||
|
|
@ -77,9 +78,9 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
|
|||
|
||||
for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) {
|
||||
|
||||
/* read it in, with any amplitude scaling */
|
||||
/* read it in directly from the source */
|
||||
|
||||
if (region->read (buf, fpos, to_read, n) != to_read) {
|
||||
if (region->source (n)->read (buf, fpos, to_read, n) != to_read) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +89,7 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
|
|||
for (nframes_t i = 0; i < to_read/2; ++i) {
|
||||
swap (buf[i],buf[to_read-1-i]);
|
||||
}
|
||||
|
||||
|
||||
/* write it out */
|
||||
|
||||
if ((*si)->write (buf, to_read) != to_read) {
|
||||
|
|
|
|||
|
|
@ -349,7 +349,12 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
|
|||
|
||||
if (_info.channels == 1) {
|
||||
nframes_t ret = sf_read_float (sf, dst, file_cnt);
|
||||
_read_data_count = cnt * sizeof(float);
|
||||
_read_data_count = ret * sizeof(float);
|
||||
if (ret != file_cnt) {
|
||||
char errbuf[256];
|
||||
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
|
||||
cerr << string_compose(_("SndFileSource: @ %1 could not read %2 within %3 (%4) (len = %5)"), start, file_cnt, _name.substr (1), errbuf, _length) << endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -413,7 +418,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
|
|||
}
|
||||
|
||||
_write_data_count = cnt;
|
||||
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue