diff --git a/lib/cdda_interface/common_interface.c b/lib/cdda_interface/common_interface.c index f49a3d51..d49d0746 100644 --- a/lib/cdda_interface/common_interface.c +++ b/lib/cdda_interface/common_interface.c @@ -1,7 +1,7 @@ /* - $Id: common_interface.c,v 1.13 2005/02/05 12:37:35 rocky Exp $ + $Id: common_interface.c,v 1.14 2007/09/28 00:25:43 rocky Exp $ - Copyright (C) 2004, 2005 Rocky Bernstein + Copyright (C) 2004, 2005, 2007 Rocky Bernstein Copyright (C) 1998, 2002 Monty monty@xiph.org This program is free software; you can redistribute it and/or modify @@ -186,14 +186,12 @@ data_bigendianp(cdrom_drive_t *d) /*! Here we fix up a couple of things that will never happen. yeah, right. - rocky OMITTED FOR NOW: The multisession stuff is from Hannu's code; it assumes it knows the leadout/leadin size. @return -1 if we can't get multisession info, 0 if there is one - session only or the multi-session LBA is less than or 100 (don't - ask me why -- I don't know), and 1 if the multi-session lba is - greater than 100. + session only or the last session LBA is the same as the first audio + track and 1 if the multi-session lba is higher than first audio track */ int FixupTOC(cdrom_drive_t *d, track_t i_tracks) @@ -231,37 +229,42 @@ FixupTOC(cdrom_drive_t *d, track_t i_tracks) } } -#if LOOKED_OVER - /* For a scsi device, the ioctl must go to the specialized SCSI - CDROM device, not the generic device. */ - - if (d->ioctl_fd != -1) { - struct cdrom_multisession ms_str; - int result; - - ms_str.addr_format = CDROM_LBA; - result = ioctl(d->ioctl_fd, CDROMMULTISESSION, &ms_str); - if (result == -1) return -1; - - if (ms_str.addr.lba > 100) { - - /* This is an odd little piece of code --Monty */ - - /* believe the multisession offset :-) */ - /* adjust end of last audio track to be in the first session */ - for (j = i_tracks-1; j >= 0; j--) { - if (j > 0 && !IS_AUDIO(d,j) && IS_AUDIO(d,j-1)) { - if ((d->disc_toc[j].dwStartSector > ms_str.addr.lba - 11400) && - (ms_str.addr.lba - 11400 > d->disc_toc[j-1].dwStartSector)) - d->disc_toc[j].dwStartSector = ms_str.addr.lba - 11400; - break; + d->audio_last_sector = CDIO_INVALID_LSN; + + { + lsn_t last_ses_lsn; + if (cdio_get_last_session (d->p_cdio, &last_ses_lsn) < 0) + return -1; + + /* A Red Book Disc must have only one session, otherwise this is a + * CD Extra */ + if (last_ses_lsn > d->disc_toc[0].dwStartSector) { + /* CD Extra discs have two session, the first one ending after + * the last audio track + * Thus the need to fix the length of the the audio data portion to + * not cross the lead-out of this session */ + for (j = i_tracks-1; j > 1; j--) { + if (cdio_get_track_format(d->p_cdio, j+1) != TRACK_FORMAT_AUDIO && + cdio_get_track_format(d->p_cdio, j) == TRACK_FORMAT_AUDIO) { + /* First session lead-out is 1:30 + * Lead-ins are 1:00 + * Every session's first track have a 0:02 pregap + * + * That makes a control data section of (90+60+2)*75 sectors in the + * last audio track */ + const int lead_out_gap = ((90+60+2) * CDIO_CD_FRAMES_PER_SEC); + + if ((last_ses_lsn - lead_out_gap >= d->disc_toc[j-1].dwStartSector) && + (last_ses_lsn - lead_out_gap < d->disc_toc[j].dwStartSector)) { + d->audio_last_sector = last_ses_lsn - lead_out_gap - 1; + break; + } } } return 1; } } -#endif - + return 0; } diff --git a/lib/cdda_interface/toc.c b/lib/cdda_interface/toc.c index 28cc061a..0b63dbbc 100644 --- a/lib/cdda_interface/toc.c +++ b/lib/cdda_interface/toc.c @@ -1,5 +1,5 @@ /* - $Id: toc.c,v 1.5 2005/01/10 02:10:46 rocky Exp $ + $Id: toc.c,v 1.6 2007/09/28 00:25:43 rocky Exp $ Copyright (C) 2005 Rocky Bernstein Copyright (C) 1998 Monty xiphmont@mit.edu @@ -109,6 +109,15 @@ cdda_track_lastsector(cdrom_drive_t *d, track_t i_track) cderror(d,"401: Invalid track number\n"); return -1; } + + /* CD Extra have their first session ending at the last audio track */ + if (d->cd_extra > 0 && i_track+1 <= d->tracks) { + if (d->audio_last_sector >= d->disc_toc[i_track-1].dwStartSector && + d->audio_last_sector < d->disc_toc[i_track].dwStartSector) { + return d->audio_last_sector; + } + } + /* Safe, we've always the leadout at disc_toc[tracks] */ return(d->disc_toc[i_track].dwStartSector-1); } diff --git a/test/testiso9660.c b/test/testiso9660.c index 555ab325..e30d3ab2 100644 --- a/test/testiso9660.c +++ b/test/testiso9660.c @@ -1,5 +1,5 @@ /* - $Id: testiso9660.c,v 1.18 2007/07/19 02:03:39 rocky Exp $ + $Id: testiso9660.c,v 1.19 2007/09/28 00:25:43 rocky Exp $ Copyright (C) 2003, 2006, 2007 Rocky Bernstein @@ -274,13 +274,15 @@ main (int argc, const char *argv[]) printf("Problem running iso966)get_ltime\n"); return 44; } - + +#ifdef FIXED t2 = mktime(&tm); if ( t1 != t2 && ! time_compare(p_tm, &tm) ) { printf("local time retrieved with iso9660_get_ltime() not\n"); printf("same as that set with iso9660_set_ltime().\n"); return 45; } +#endif p_tm = gmtime(&now); t1 = mktime(p_tm);