From 2072261bb07aac3d84f2cb0959042f5289f200dc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 18 Apr 2012 22:22:47 +0000 Subject: Re-work fade operation to be closer to Mixbus; things below the top region's fades are implicitly faded in the opposite sense; restore short crossfades option. git-svn-id: svn://localhost/ardour2/branches/3.0@12022 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/audio_playlist.cc | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'libs/ardour/audio_playlist.cc') diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index bcb0219e2a..47b2a5809a 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -149,6 +149,17 @@ struct ReadSorter { } }; +/** A segment of region that needs to be read */ +struct Segment { + Segment (boost::shared_ptr r, Evoral::Range a) : region (r), range (a) {} + + boost::shared_ptr region; ///< the region + Evoral::Range range; ///< range of the region to read, in session frames +}; + +/** @param start Start position in session frames. + * @param cnt Number of frames to read. + */ ARDOUR::framecnt_t AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, framepos_t start, framecnt_t cnt, unsigned chan_n) @@ -184,16 +195,18 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr all->sort (ReadSorter ()); /* This will be a list of the bits of our read range that we have - read completely (ie for which no more regions need to be read). + handled completely (ie for which no more regions need to be read). It is a list of ranges in session frames. */ Evoral::RangeList done; + + /* This will be a list of the bits of regions that we need to read */ + list to_do; + /* Now go through the `all' list filling in `to_do' and `done' */ for (RegionList::iterator i = all->begin(); i != all->end(); ++i) { boost::shared_ptr ar = boost::dynamic_pointer_cast (*i); - /* Trim region range to the bit we are reading */ - /* Work out which bits of this region need to be read; first, trim to the range we are reading... */ @@ -202,19 +215,17 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr region_range.to = min (region_range.to, start + cnt - 1); /* ... and then remove the bits that are already done */ - Evoral::RangeList to_do = Evoral::subtract (region_range, done); + Evoral::RangeList region_to_do = Evoral::subtract (region_range, done); /* Read those bits, adding their bodies (the parts between end-of-fade-in and start-of-fade-out) to the `done' list. */ - Evoral::RangeList::List t = to_do.get (); - - for (Evoral::RangeList::List::iterator i = t.begin(); i != t.end(); ++i) { - Evoral::Range d = *i; + Evoral::RangeList::List t = region_to_do.get (); - /* Read the whole range, possibly including fades */ - ar->read_at (buf + d.from - start, mixdown_buffer, gain_buffer, d.from, d.to - d.from + 1, chan_n); + for (Evoral::RangeList::List::iterator j = t.begin(); j != t.end(); ++j) { + Evoral::Range d = *j; + to_do.push_back (Segment (ar, d)); if (ar->opaque ()) { /* Cut this range down to just the body and mark it done */ @@ -228,6 +239,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr } } + /* Now go backwards through the to_do list doing the actual reads */ + for (list::reverse_iterator i = to_do.rbegin(); i != to_do.rend(); ++i) { + i->region->read_at (buf + i->range.from - start, mixdown_buffer, gain_buffer, i->range.from, i->range.to - i->range.from + 1, chan_n); + } + return cnt; } -- cgit v1.2.3