diff --git a/include/cdio/cdda.h b/include/cdio/cdda.h index e3c55f9d..e03b4ee1 100644 --- a/include/cdio/cdda.h +++ b/include/cdio/cdda.h @@ -1,5 +1,5 @@ /* - $Id: cdda.h,v 1.3 2005/01/08 20:39:40 rocky Exp $ + $Id: cdda.h,v 1.4 2005/01/10 02:10:46 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein Copyright (C) 2001 Xiph.org @@ -78,7 +78,11 @@ struct cdrom_drive_s { int cd_extra; track_t tracks; - TOC_t disc_toc[MAXTRK]; + TOC_t disc_toc[MAXTRK]; /**< info here starts origin 0 rather than the + first track number (usually 1). So to take + a track number and use it here, subtract + off cdio_get_first_track_num() beforehand. + */ lsn_t audio_first_sector; lsn_t audio_last_sector; @@ -170,7 +174,7 @@ extern int cdda_track_preemp(cdrom_drive_t *d, track_t i_track); /*! Get first lsn of the first audio track. -1 is returned on error. */ extern lsn_t cdda_disc_firstsector(cdrom_drive_t *d); -/*! Get last lsn of the last audio track. The last lssn generally one +/*! Get last lsn of the last audio track. The last lsn is generally one less than the start of the next track after the audio track. -1 is returned on error. */ extern lsn_t cdda_disc_lastsector(cdrom_drive_t *d); diff --git a/lib/cdda_interface/toc.c b/lib/cdda_interface/toc.c index 76f2e6ac..28cc061a 100644 --- a/lib/cdda_interface/toc.c +++ b/lib/cdda_interface/toc.c @@ -1,5 +1,5 @@ /* - $Id: toc.c,v 1.4 2005/01/06 23:32:58 rocky Exp $ + $Id: toc.c,v 1.5 2005/01/10 02:10:46 rocky Exp $ Copyright (C) 2005 Rocky Bernstein Copyright (C) 1998 Monty xiphmont@mit.edu @@ -54,7 +54,11 @@ cdda_track_firstsector(cdrom_drive_t *d, track_t i_track) cderror(d,"401: Invalid track number\n"); return(-1); } - return(d->disc_toc[i_track-1].dwStartSector); + + { + const track_t i_first_track = cdio_get_first_track_num(d->p_cdio); + return(d->disc_toc[i_track-i_first_track].dwStartSector); + } } /*! Get first lsn of the first audio track. -1 is returned on error. */ @@ -115,17 +119,17 @@ cdda_track_lastsector(cdrom_drive_t *d, track_t i_track) lsn_t cdda_disc_lastsector(cdrom_drive_t *d) { - int i; if (!d->opened) { cderror(d,"400: Device not open\n"); return -1; + } else { + /* look for an audio track */ + const track_t i_first_track = cdio_get_first_track_num(d->p_cdio); + track_t i = cdio_get_last_track_num(d->p_cdio); + for ( ; i >= i_first_track; i-- ) + if ( cdda_track_audiop(d,i) ) + return (cdda_track_lastsector(d,i)); } - - /* look for an audio track */ - for ( i=d->tracks-1; i>=0; i-- ) - if ( cdda_track_audiop(d,i+1) == 1 ) - return (cdda_track_lastsector(d,i+1)); - cderror(d,"403: No audio tracks on disc\n"); return -1; } diff --git a/lib/paranoia/p_block.c b/lib/paranoia/p_block.c index 68f5b831..e1fcd5d9 100644 --- a/lib/paranoia/p_block.c +++ b/lib/paranoia/p_block.c @@ -1,5 +1,5 @@ /* - $Id: p_block.c,v 1.4 2005/01/07 02:42:29 rocky Exp $ + $Id: p_block.c,v 1.5 2005/01/10 02:10:47 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein Copyright (C) 1998 Monty xiphmont@mit.edu @@ -367,24 +367,53 @@ c_removef(c_block_t *v, long cut) /**** Initialization *************************************************/ +/*! Get the beginning and ending sector bounds given cursor position. + + There are a couple of subtle differences between this and the + cdda_firsttrack_sector and cdda_lasttrack_sector. If the cursor is + an a sector later than cdda_firsttrack_sector, that sectur will be + used. As for the difference between cdda_lasttrack_sector, if the CD + is mixed and there is a data track after the cursor but before the + last audio track, the end of the audio sector before that is used. +*/ void i_paranoia_firstlast(cdrom_paranoia_t *p) { - int i; + track_t i, j; cdrom_drive_t *d=p->d; - p->current_lastsector=-1; - for(i=cdda_sector_gettrack(d,p->cursor);icurrent_lastsector=cdda_track_lastsector(d,i-1); - if(p->current_lastsector==-1) - p->current_lastsector=cdda_disc_lastsector(d); + const track_t i_first_track = cdio_get_first_track_num(d->p_cdio); + const track_t i_last_track = cdio_get_last_track_num(d->p_cdio); - p->current_firstsector=-1; - for(i=cdda_sector_gettrack(d,p->cursor);i>0;i--) - if(!cdda_track_audiop(d,i)) - p->current_firstsector=cdda_track_firstsector(d,i+1); - if(p->current_firstsector==-1) - p->current_firstsector=cdda_disc_firstsector(d); + p->current_lastsector = p->current_firstsector = -1; + + i = cdda_sector_gettrack(d, p->cursor); + + if ( CDIO_INVALID_TRACK != i ) { + if ( 0 == i ) i++; + j = i; + /* In the below loops, We assume the cursor already is on an audio + sector. Not sure if this is correct if p->cursor is in the pregap + before the first track. + */ + for ( ; i < i_last_track; i++) + if( !cdda_track_audiop(d,i) ) { + p->current_lastsector=cdda_track_lastsector(d,i-1); + break; + } + + i = j; + for ( ; i >= i_first_track; i-- ) + if( !cdda_track_audiop(d,i) ) { + p->current_firstsector = cdda_track_firstsector(d,i+1); + break; + } + } + + if (p->current_lastsector == -1) + p->current_lastsector = cdda_disc_lastsector(d); + + if(p->current_firstsector == -1) + p->current_firstsector = cdda_disc_firstsector(d); }