- return cnt;
-}
-
-void
-AudioPlaylist::check_crossfades (Evoral::Range<framepos_t> range)
-{
- if (in_set_state || in_partition || !_session.config.get_auto_xfade ()) {
- return;
- }
-
- boost::shared_ptr<RegionList> starts = regions_with_start_within (range);
- boost::shared_ptr<RegionList> ends = regions_with_end_within (range);
-
- RegionList all = *starts;
- std::copy (ends->begin(), ends->end(), back_inserter (all));
-
- all.sort (RegionSortByLayer ());
-
- set<boost::shared_ptr<Region> > done_start;
- set<boost::shared_ptr<Region> > done_end;
-
- for (RegionList::reverse_iterator i = all.rbegin(); i != all.rend(); ++i) {
- for (RegionList::reverse_iterator j = all.rbegin(); j != all.rend(); ++j) {
-
- if (i == j) {
- continue;
- }
-
- if ((*i)->muted() || (*j)->muted()) {
- continue;
- }
-
- if ((*i)->position() == (*j)->position() && ((*i)->length() == (*j)->length())) {
- /* precise overlay: no xfade */
- continue;
- }
-
- if ((*i)->position() == (*j)->position() || ((*i)->last_frame() == (*j)->last_frame())) {
- /* starts or ends match: no xfade */
- continue;
- }
-
-
- boost::shared_ptr<AudioRegion> top;
- boost::shared_ptr<AudioRegion> bottom;
-
- if ((*i)->layer() < (*j)->layer()) {
- top = boost::dynamic_pointer_cast<AudioRegion> (*j);
- bottom = boost::dynamic_pointer_cast<AudioRegion> (*i);
- } else {
- top = boost::dynamic_pointer_cast<AudioRegion> (*i);
- bottom = boost::dynamic_pointer_cast<AudioRegion> (*j);
- }
-
- if (!top->opaque ()) {
- continue;
- }
-
- Evoral::OverlapType const c = top->coverage (bottom->position(), bottom->last_frame());
-
- if (c == Evoral::OverlapStart) {
-
- /* top starts within bottom but covers bottom's end */
-
- /* { ==== top ============ }
- * [---- bottom -------------------]
- */
-
- if (done_start.find (top) == done_start.end() && done_end.find (bottom) == done_end.end ()) {
- framecnt_t const len = bottom->last_frame () - top->first_frame ();
- top->set_fade_in_length (len);
- top->set_fade_in_active (true);
- done_start.insert (top);
- bottom->set_fade_out_length (len);
- bottom->set_fade_out_active (true);
- done_end.insert (bottom);
- }
-
- } else if (c == Evoral::OverlapEnd) {
-
- /* top covers start of bottom but ends within it */
-
- /* [---- top ------------------------]
- * { ==== bottom ============ }
- */
-
- if (done_end.find (top) == done_end.end() && done_start.find (bottom) == done_start.end ()) {
- framecnt_t const len = top->last_frame () - bottom->first_frame ();
- top->set_fade_out_length (len);
- top->set_fade_out_active (true);
- done_end.insert (top);
- bottom->set_fade_in_length (len);
- bottom->set_fade_in_active (true);
- done_start.insert (bottom);
- }
- }
- }
- }
-
- for (RegionList::iterator i = starts->begin(); i != starts->end(); ++i) {
- if (done_start.find (*i) == done_start.end()) {
- boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (*i);
- r->set_default_fade_in ();
- }
+ /* Now go backwards through the to_do list doing the actual reads */
+ for (list<Segment>::reverse_iterator i = to_do.rbegin(); i != to_do.rend(); ++i) {
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\tPlaylist %1 read %2 @ %3 for %4, channel %5, buf @ %6 offset %7\n",
+ name(), i->region->name(), i->range.from,
+ i->range.to - i->range.from + 1, (int) chan_n,
+ buf, i->range.from - start));
+ 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);