+ boost::shared_ptr<AudioRegion> result;
+
+ cerr << "RBEffect: source region: position = " << region->position()
+ << ", start = " << region->start()
+ << ", length = " << region->length()
+ << ", ancestral_start = " << region->ancestral_start()
+ << ", ancestral_length = " << region->ancestral_length()
+ << ", stretch " << region->stretch()
+ << ", shift " << region->shift() << endl;
+
+ /*
+ We have two cases to consider:
+
+ 1. The region has not been stretched before.
+
+ In this case, we just want to read region->length() frames
+ from region->start().
+
+ We will create a new region of region->length() *
+ tsr.time_fraction frames. The new region will have its
+ start set to 0 (because it has a new audio file that begins
+ at the start of the stretched area) and its ancestral_start
+ set to region->start() (so that we know where to begin
+ reading if we want to stretch it again).
+
+ 2. The region has been stretched before.
+
+ The region starts at region->start() frames into its
+ (possibly previously stretched) source file. But we don't
+ want to read from its source file; we want to read from the
+ file it was originally stretched from.
+
+ The region's source begins at region->ancestral_start()
+ frames into its master source file. Thus, we need to start
+ reading at region->ancestral_start() + (region->start() /
+ region->stretch()) frames into the master source. This
+ value will also become the ancestral_start for the new
+ region.
+
+ We cannot use region->ancestral_length() to establish how
+ many frames to read, because it won't be up to date if the
+ region has been trimmed since it was last stretched. We
+ must read region->length() / region->stretch() frames and
+ stretch them by tsr.time_fraction * region->stretch(), for
+ a new region of region->length() * tsr.time_fraction
+ frames.
+
+ Case 1 is of course a special case of 2, where
+ region->ancestral_start() == 0 and region->stretch() == 1.
+
+ When we ask to read from a region, we supply a position on
+ the global timeline. The read function calculates the
+ offset into the source as (position - region->position()) +
+ region->start(). This calculation is used regardless of
+ whether we are reading from a master or
+ previously-stretched region. In order to read from a point
+ n frames into the master source, we need to provide n -
+ region->start() + region->position() as our position
+ argument to master_read_at().
+
+ Note that region->ancestral_length() is not used.
+
+ I hope this is clear.
+ */