Timeline: Fix rare segfault which occurred when region loop point is just beyond the end of a region and at the beginning of a buffer.
This commit is contained in:
parent
5378bbbb27
commit
b13d2da674
|
@ -118,10 +118,12 @@ Audio_Region::read ( sample_t *buf, bool buf_is_empty, nframes_t pos, nframes_t
|
|||
|
||||
const Range r = _range;
|
||||
|
||||
/* ASSERT( r.legnth > 0, "Region has zero length!" ); */
|
||||
|
||||
const nframes_t rS = r.start;
|
||||
const nframes_t rE = r.start + r.length;
|
||||
const nframes_t rE = r.start + r.length; /* one more than the last frame of the region! */
|
||||
const nframes_t bS = pos;
|
||||
const nframes_t bE = pos + nframes;
|
||||
const nframes_t bE = pos + nframes; /* one more than the last frame of the buffer! */
|
||||
|
||||
/* do nothing if region isn't inside buffer */
|
||||
if ( bS > rE || bE < rS )
|
||||
|
@ -188,20 +190,42 @@ Audio_Region::read ( sample_t *buf, bool buf_is_empty, nframes_t pos, nframes_t
|
|||
WARNING("Loop size (%lu) is smaller than buffer size (%lu). Behavior undefined.", _loop, nframes );
|
||||
}
|
||||
|
||||
const nframes_t lO = sO % _loop; /* how far we are into the loop */
|
||||
const nframes_t nthloop = sO / _loop; /* which loop iteration */
|
||||
const nframes_t seam_L = rS + ( nthloop * _loop ); /* receding seam */
|
||||
const nframes_t seam_R = rS + ( (nthloop + 1 ) * _loop ); /* upcoming seam */
|
||||
|
||||
/* read interleaved channels */
|
||||
if ( seam_R > bS && seam_R < bE )
|
||||
{
|
||||
/* this buffer covers a loop boundary */
|
||||
const nframes_t lO = sO % _loop, /* how far we are into the loop */
|
||||
nthloop = sO / _loop, /* which loop iteration */
|
||||
seam_L = rS + ( nthloop * _loop ), /* receding seam */
|
||||
seam_R = rS + ( ( nthloop + 1 ) * _loop ); /* upcoming seam */
|
||||
|
||||
/* read interleaved channels */
|
||||
if (
|
||||
/* this buffer contains a loop boundary, which lies on neither the first or the last frame, and therefore requires a splice of two reads from separate parts of the region. */
|
||||
seam_R > bS && seam_R < bE
|
||||
&&
|
||||
/* but if the end seam of the loop is also the end seam of the region, we only need one read */
|
||||
seam_R != rE
|
||||
&&
|
||||
/* also, if the seam is within the buffer, but beyond the end of the region (as in last loop iteration), do the simpler read in the else clause */
|
||||
seam_R <= rE
|
||||
)
|
||||
{
|
||||
/* this buffer covers a loop boundary */
|
||||
|
||||
/* read the first part */
|
||||
cnt = _clip->read( cbuf + ( _clip->channels() * bO ), -1, r.offset + lO, ( seam_R - bS ) - bO );
|
||||
cnt = _clip->read(
|
||||
cbuf + ( _clip->channels() * bO ), /* buf */
|
||||
-1, /* chan */
|
||||
r.offset + lO, /* start */
|
||||
( seam_R - bS ) - bO /* len */
|
||||
);
|
||||
|
||||
/* ASSERT( len > cnt, "Error in region looping calculations" ); */
|
||||
|
||||
/* read the second part */
|
||||
cnt += _clip->read( cbuf + ( _clip->channels() * ( bO + cnt ) ), -1, r.offset + 0, ( len - cnt ) - bO );
|
||||
cnt += _clip->read(
|
||||
cbuf + ( _clip->channels() * ( bO + cnt ) ), /* buf */
|
||||
-1, /* chan */
|
||||
r.offset + 0, /* start */
|
||||
( len - cnt ) - bO /* len */
|
||||
);
|
||||
|
||||
/* assert( cnt == len ); */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue