Thanks! I'll apply this privately at home tonight and look at it then. Just two more days until 0.80 is released and then this will go into trunk. (I'm not sure I want to create a branch for what amounts to two days.)
Robert William Fuller writes: > This is the whole shebang minus the regression tests. It includes the > modifications to the documentation, pre-gap support for cdrdao in > addition to nrg and bin/cue, as well as updates to the library > revisions. The only thing missing is regression tests. Hopefully, I'll > get to those shortly. > > It turns out texi is pretty easy. I didn't even need to read the > documentation! (Although I probably should....) > > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/doc/libcdio.texi libcdio-0.80/doc/libcdio.texi > --- libcdio-0.80-clean/doc/libcdio.texi 2007-12-15 17:35:53.000000000 > -0500 > +++ libcdio-0.80/doc/libcdio.texi 2008-03-13 14:26:00.000000000 -0400 > @@ -876,18 +876,20 @@ > @menu > * Tracks:: Tracks > * Sectors:: Block addressing (MSF, LSN, LBA) > +* Pre-gaps:: Track pre-gaps > @end menu > > @node Tracks > @section tracks --- disc subdivisions > @cindex track > [EMAIL PROTECTED] gaps > > In this section we describe CD properties and terms that we make use > of in @value{libcdio}. > > A CD is formated into a number of @term{tracks}, and a CD can hold at > most 99 such tracks. This is defined by @code{CDIO_CD_MAX_TRACKS} in > [EMAIL PROTECTED]/sector.h}. Between the tracks CD specifications require a > [EMAIL PROTECTED]/sector.h}. Between some tracks CD specifications require a > ``2 second'' in gap (called a @term{lead-in gap}. This is unused space > with no ``data'' similar to the space between tracks on an old > phonograph. The word ``second'' here really refers to a measure of > @@ -900,9 +902,9 @@ > second'' lead-in gap and there is supposed to be another ``2 second'' > @term{lead-out} gap at the end (or outer edge) of the CD. > > -People have discovered that they can put useful data in the various > -gaps and their equipment can read this, violating the standards but > -allowing a CD to store more data. > +People have discovered that they can put useful data in the @term{lead-in} > +and @term{lead-out} gaps, and their equipment can read this, violating > +the standards but allowing a CD to store more data. > > In order to determine the number of tracks on a CD and where they > start, commands are used to get this table-of-contents or @term{TOC} > @@ -922,7 +924,7 @@ > @cindex frames > > A track is broken up into a number of 2352-byte @emph{blocks} which we > -sometimes call @emph{sectors} or @emph{frames}. Whereas tracks have to > +sometimes call @emph{sectors} or @emph{frames}. Whereas tracks may > have a gap between them, a block or sector does not. (In > @value{libcdio} the block size constant is defined using > @code{CDIO_CD_FRAMESIZE_RAW}). > @@ -981,6 +983,138 @@ > add 150. Why the distinction between LBA and LSN? I don't know, > perhaps this has something to do with ``multisession'' CDs. > > [EMAIL PROTECTED] Pre-gaps > [EMAIL PROTECTED] track pre-gaps -- @acronym{CD-DA} discs and gaps > [EMAIL PROTECTED] CD-DA > [EMAIL PROTECTED] gaps > [EMAIL PROTECTED] lead in > [EMAIL PROTECTED] lead out > [EMAIL PROTECTED] pre-gap > [EMAIL PROTECTED] Q sub-channel > + > +Gaps are possibly one of the least understood topics in audio discs. > +In the case of @acronym{CD-DA} discs, standards require a silent 2 > +second gap before the first audio track and after the last audio track > +(in each session.) These are respectively referred to as > [EMAIL PROTECTED] and @term{lead-out} gaps. No other gaps are required. > +It is important not to confuse the required @term{lead-in} and > [EMAIL PROTECTED] gaps with the optional track @term{pre-gap}s. Track > [EMAIL PROTECTED] are the gaps that may occur between audio tracks. > +Typically, track @term{pre-gap}s are filled with silence so that the > +listener knows that one song has ended, and the next will soon begin. > +However, track @term{pre-gap}s do not have to contain silence. One > +exception is an audio disc of a live performance. Because the > +performer may seamlessly move from one piece of the performance to the > +next, it would be unnatural for the disc to contain silence between > +the two pieces. Instead, the track number updates with no > +interruption in the performance. This allows the listener to either > +hear the entire performance without unnatural interruptions, or to > +conveniently skip to certain pieces of the performance. Finally, some > [EMAIL PROTECTED] discs--whose behavior will be described below--lack > +track @term{pre-gap}s altogether although they must still include the > [EMAIL PROTECTED] and @term{lead-out} gaps. > + > +In order to understand the track @term{pre-gap}s that occur between > +audio tracks, it is necessary to understand how CD players display the > +track number and time. Embedded in each block of audio data is > +non-audio information known as the @term{Q sub-channel}. The > [EMAIL PROTECTED] sub-channel} data tells the CD player what track number > and time > +it should display while it is playing the block of audio data in which > +the @term{Q sub-channel} data is embedded. Near the end of some > +tracks, the @term{Q sub-channel} may instruct the CD player to update > +the track number to the next track, and display a count down to the > +next track, often starting at -2 seconds and proceeding to zero. This > +is known as an audio track @term{pre-gap}. It may either contain > +silence, or as previously discussed--in the case of live > +performances--it may contain audio. Almost as often as not, there is > +no @term{pre-gap} whatsoever. Regardless, an audio track > [EMAIL PROTECTED] is purely determined by the contents of the > [EMAIL PROTECTED] sub-channel}, which is embedded in each audio sector. > This has > +some interesting implications for the track forward button. > + > +When the track forward button is pressed on a CD player, the CD player > +advances to the next track, skipping that track's @term{pre-gap}. > +This is because the CD player uses the starting address of the track > +from the disc's table of contents (TOC) to determine where to start > +playing a track when either the track forward or track backward > +buttons are pressed. So to hear a @term{pre-gap} for track 4, the > +listener must either listen to track 3 first, or use the track forward > +or backward buttons to go to track 4, then use the seek backward > +button to back up into track 4's @term{pre-gap}, which is really part > +of track 3, at least according to the TOC. Track 1 @term{pre-gap}s > +are especially interesting because some commercial discs have audio > +hidden before the beginning of the first track! The only way to hear > +this hidden audio with a standard player is to use the seek backward > +button as soon as track 1 begins playing! > + > +Audio track @term{pre-gap}s may be specified in a couple of different > +ways in the popular cue file format. The first way of specifying a > [EMAIL PROTECTED] is to use the @command{PREGAP} command. This will > +place a @term{pre-gap} containing silence before a track. The second > +way of specifying a @term{pre-gap} is to give a track an > [EMAIL PROTECTED] 00} as well as the more normal @command{INDEX 01}. > [EMAIL PROTECTED] 01} will be used to specify the start of the track in > +the disc's TOC, while @command{INDEX 00} will be used to specify the > +start of the track's @term{pre-gap} as recorded in the @term{Q sub-channel}. > [EMAIL PROTECTED] 00} is ordinarily used for specifying > +track @term{pre-gap}s that contain audio rather than silence. Thus, > +the cue file format may be used to specify track @term{pre-gap}s with > +silence or audio, depending on whether the @command{PREGAP} or > [EMAIL PROTECTED] 00} commands are specified. If neither type of > [EMAIL PROTECTED] is specified for a track, no @term{pre-gap} is created > +for that track, which merely means the absence of @term{pre-gap} > +information in the @term{Q sub-channel}, and the lack of a short count > +down to the next track. > + > +Various @acronym{CD-DA} ripping programs take various approaches to > +track @term{pre-gap}s. Some ripping programs ignore track > [EMAIL PROTECTED] altogether, relying solely on the disc's TOC to > +determine where tracks begin and end. If a disc is ripped with such a > +program, then re-burned later, the resulting disc will lack track > [EMAIL PROTECTED], and thereby lack the playback behavior of counting > +down to the next track. Other ripping programs detect track > [EMAIL PROTECTED] and record them in the popular cue file format among > +others. Such ripping programs sometimes allow the user to determine > +whether track @term{pre-gap}s will be appended to the prior track or > +pre-pended to the track to which they "belong". Note that if a > +ripping program is ignorant of track @term{pre-gap}s, the track > [EMAIL PROTECTED] will be appended to the prior track, because that is > +where the disc's TOC puts them. Thus, there are many different ways > +an application may chose to deal with track @term{pre-gap}s. > +Consequently, @kbd{libcdio} does not dictate the policy a ripping > +program should use in dealing with track @term{pre-gap}s. Hence, > [EMAIL PROTECTED] provides the @code{cdio_get_track_pregap_[lba|lsn]()} > +interfaces to allow the application to deal with track @term{pre-gap}s > +as it sees fit. > + > +Note that the @code{cdio_get_track_pregap_[lba|lsn]()} interfaces > +currently only provide information for CDRDAO TOC, CDRWIN BIN/CUE, and > +NRG images. Getting the track @term{pre-gap}s from a CD drive is a > +more complicated problem because not all CD drives support reading the > [EMAIL PROTECTED] sub-channel} DIRECTLY at @emph{high} speed, and there is no > +interface to determine whether or not a drive supports this optional > +feature, aside from trying to read the @term{Q sub-channel}, and > +possibly incurring IO errors. However, all drives DO support reading > +the @term{Q sub-channel} INDIRECTLY while playing an audio disc by > +asking the drive for the current position. Unfortunately, this occurs > +at normal playback speed, and requires a certain settling time after > +the disc starts playing. Thus, using this @emph{slow} interface > +requires a more sophisticated algorithm, such as binary search or some > +heuristic, like backing up progressively from the end of the prior > +track to look for the next track's @term{pre-gap}. Note that CD > +drives seek @emph{slow}ly, so it is better to simply use a drive that > +can read the @term{Q sub-channel} directly at @emph{high} speed, and > +avoid complicated software solutions. (Not to mention that if the > +user has an older system with an analog audio cable hooked up between > +their soundboard and their drive, and a ripping program uses the > [EMAIL PROTECTED] interface, the user will hear bits of the audio on the > +disc!) Consequently, because there is no good universal solution to > +the problem of reading the @term{Q sub-channel} from a drive, > [EMAIL PROTECTED] currently leaves this problem up to the application, a > +problem which is readily approachable through either @kbd{libcdio}'s > +MMC interface or @kbd{libcdio}'s cdda interface. For an example of > +one such application, see @url{https://gna.org/projects/cued/}. > + > @node How to use > @chapter How to use > > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/include/cdio/track.h libcdio-0.80/include/cdio/track.h > --- libcdio-0.80-clean/include/cdio/track.h 2006-01-23 15:30:28.000000000 > -0500 > +++ libcdio-0.80/include/cdio/track.h 2008-03-10 16:15:32.000000000 > -0400 > @@ -196,6 +196,28 @@ > @return the starting LSN or CDIO_INVALID_LSN on error. > */ > lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track); > + > + /*! > + Return the starting LBA for the pregap for track number > + i_track in p_cdio. Track numbers usually start at something > + greater than 0, usually 1. > + > + @param p_cdio object to get information from > + @param i_track the track number we want the LBA for > + @return the starting LBA or CDIO_INVALID_LBA on error. > + */ > + lba_t cdio_get_track_pregap_lba(const CdIo_t *p_cdio, track_t i_track); > + > + /*! > + Return the starting LSN for the pregap for track number > + i_track in p_cdio. Track numbers usually start at something > + greater than 0, usually 1. > + > + @param p_cdio object to get information from > + @param i_track the track number we want the LSN for > + @return the starting LSN or CDIO_INVALID_LSN on error. > + */ > + lsn_t cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track); > > /*! > Return the starting MSF (minutes/secs/frames) for track number > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/Makefile.am libcdio-0.80/lib/driver/Makefile.am > --- libcdio-0.80-clean/lib/driver/Makefile.am 2007-10-15 > 00:53:59.000000000 -0400 > +++ libcdio-0.80/lib/driver/Makefile.am 2008-03-11 22:20:26.000000000 > -0400 > @@ -43,9 +43,9 @@ > # public release, then set AGE to 0. A changed interface means an > # incompatibility with previous versions. > > -libcdio_la_CURRENT = 8 > -libcdio_la_REVISION = 1 > -libcdio_la_AGE = 1 > +libcdio_la_CURRENT = 9 > +libcdio_la_REVISION = 0 > +libcdio_la_AGE = 2 > > EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \ > libcdio.sym > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/cdio_private.h > libcdio-0.80/lib/driver/cdio_private.h > --- libcdio-0.80-clean/lib/driver/cdio_private.h 2006-01-23 > 15:48:11.000000000 -0500 > +++ libcdio-0.80/lib/driver/cdio_private.h 2008-03-09 21:23:04.000000000 > -0400 > @@ -260,6 +260,13 @@ > CDIO_INVALID_LBA is returned on error. > */ > lba_t (*get_track_lba) ( void *p_env, track_t i_track ); > + > + /*! > + Return the starting LBA for the pregap for track number > + i_track in p_env. Tracks numbers start at 1. > + CDIO_INVALID_LBA is returned on error. > + */ > + lba_t (*get_track_pregap_lba) ( const void *p_env, track_t i_track ); > > /*! > Get format of track. > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image/bincue.c > libcdio-0.80/lib/driver/image/bincue.c > --- libcdio-0.80-clean/lib/driver/image/bincue.c 2006-02-13 > 06:00:53.000000000 -0500 > +++ libcdio-0.80/lib/driver/image/bincue.c 2008-03-10 17:28:43.000000000 > -0400 > @@ -632,7 +632,7 @@ > goto err_exit; > } > if (cd) { > - cd->tocent[i].pregap = lba; > + cd->tocent[i].silence = lba; > } > } else { > goto format_error; > @@ -672,7 +672,14 @@ > track_info_t *this_track= > &(cd->tocent[cd->gen.i_tracks - cd->gen.i_first_track]); > > - if (start_index != 0) { > + switch (start_index) { > + > + case 0: > + lba += CDIO_PREGAP_SECTORS; > + this_track->pregap = lba; > + break; > + > + case 1: > if (!b_first_index_for_track) { > lba += CDIO_PREGAP_SECTORS; > cdio_lba_to_msf(lba, &(this_track->start_msf)); > @@ -709,6 +716,10 @@ > } > } > this_track->num_indices++; > + break; > + > + default: > + break; > } > } > #endif > @@ -1163,6 +1174,7 @@ > _funcs.get_track_lba = _get_lba_track_bincue; > _funcs.get_track_msf = _get_track_msf_image; > _funcs.get_track_preemphasis = get_track_preemphasis_image, > + _funcs.get_track_pregap_lba = get_track_pregap_lba_image; > _funcs.lseek = _lseek_bincue; > _funcs.read = _read_bincue; > _funcs.read_audio_sectors = _read_audio_sectors_bincue; > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image/cdrdao.c > libcdio-0.80/lib/driver/image/cdrdao.c > --- libcdio-0.80-clean/lib/driver/image/cdrdao.c 2007-03-05 > 06:49:24.000000000 -0500 > +++ libcdio-0.80/lib/driver/image/cdrdao.c 2008-03-13 13:24:34.000000000 > -0400 > @@ -825,6 +825,7 @@ > if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { > /* todo: line is too long! */ > if (NULL != cd) { > + cd->tocent[i].pregap = cd->tocent[i].start_lba; > cd->tocent[i].start_lba += cdio_mmssff_to_lba (psz_field); > cdio_lba_to_msf(cd->tocent[i].start_lba, > &(cd->tocent[i].start_msf)); > @@ -843,7 +844,7 @@ > if (0 <= i) { > if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { > if (NULL != cd) > - cd->tocent[i].pregap = cdio_mmssff_to_lba (psz_field); > + cd->tocent[i].silence = cdio_mmssff_to_lba (psz_field); > } else { > goto format_error; > } > @@ -1295,6 +1296,7 @@ > _funcs.get_track_lba = _get_lba_track_cdrdao; > _funcs.get_track_msf = _get_track_msf_image; > _funcs.get_track_preemphasis = get_track_preemphasis_image, > + _funcs.get_track_pregap_lba = get_track_pregap_lba_image; > _funcs.lseek = _lseek_cdrdao; > _funcs.read = _read_cdrdao; > _funcs.read_audio_sectors = _read_audio_sectors_cdrdao; > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image/nrg.c libcdio-0.80/lib/driver/image/nrg.c > --- libcdio-0.80-clean/lib/driver/image/nrg.c 2008-03-03 > 07:04:34.000000000 -0500 > +++ libcdio-0.80/lib/driver/image/nrg.c 2008-03-13 13:36:30.000000000 > -0400 > @@ -371,24 +371,24 @@ > case DAOX_ID: /* "DAOX" */ > case DAOI_ID: /* "DAOI" */ > { > + _daox_t *_xentries = NULL; > + _daoi_t *_ientries = NULL; > + _dao_common_t *_dao_common = (void *) chunk->data; > + int disc_mode = _dao_common->unknown[1]; > track_format_t track_format; > - int disc_mode; > + int i; > > /* We include an extra 0 byte so these can be used as C strings.*/ > - p_env->psz_mcn = calloc(1, CDIO_MCN_SIZE+1); > + p_env->psz_mcn = calloc(1, CDIO_MCN_SIZE+1); > + memcpy(p_env->psz_mcn, &(_dao_common->psz_mcn), CDIO_MCN_SIZE); > + p_env->psz_mcn[CDIO_MCN_SIZE] = '\0'; > > if (DAOX_ID == opcode) { > - _daox_array_t *_entries = (void *) chunk->data; > - disc_mode = _entries->_unknown[1]; > - p_env->dtyp = _entries->_unknown[19]; > - memcpy(p_env->psz_mcn, &(_entries->psz_mcn), CDIO_MCN_SIZE); > - p_env->psz_mcn[CDIO_MCN_SIZE] = '\0'; > + _xentries = (void *) chunk->data; > + p_env->dtyp = _xentries->track_info[0].common.unknown[0]; > } else { > - _daoi_array_t *_entries = (void *) chunk->data; > - disc_mode = _entries->_unknown[1]; > - p_env->dtyp = _entries->_unknown[19]; > - memcpy(p_env->psz_mcn, &(_entries->psz_mcn), CDIO_MCN_SIZE); > - p_env->psz_mcn[CDIO_MCN_SIZE] = '\0'; > + _ientries = (void *) chunk->data; > + p_env->dtyp = _ientries->track_info[0].common.unknown[0]; > } > > p_env->is_dao = true; > @@ -430,7 +430,6 @@ > track_format = TRACK_FORMAT_AUDIO; > } > if (0 == disc_mode) { > - int i; > for (i=0; i<p_env->gen.i_tracks; i++) { > cdtext_init (&(p_env->gen.cdtext_track[i])); > p_env->tocent[i].track_format= track_format; > @@ -446,7 +445,6 @@ > } > } > } else if (2 == disc_mode) { > - int i; > for (i=0; i<p_env->gen.i_tracks; i++) { > cdtext_init (&(p_env->gen.cdtext_track[i])); > p_env->tocent[i].track_green = true; > @@ -473,6 +471,20 @@ > "Don't know if mode 1, mode 2 or mixed: %x\n", > disc_mode); > } > + > + for (i=0; i<p_env->gen.i_tracks; i++) { > + if (!p_env->tocent[i].datasize) { > + continue; > + } > + if (DAOX_ID == opcode) { > + p_env->tocent[i].pregap = (uint64_from_be > + (_xentries->track_info[i].index0)) / > (p_env->tocent[i].datasize); > + } else { > + p_env->tocent[i].pregap = (uint32_from_be > + (_ientries->track_info[i].index0)) / > (p_env->tocent[i].datasize); > + } > + } > + > break; > } > case NERO_ID: > @@ -1243,13 +1255,14 @@ > _funcs.get_media_changed = get_media_changed_image; > _funcs.get_mcn = _get_mcn_image; > _funcs.get_num_tracks = _get_num_tracks_image; > - _funcs.get_track_channels = get_track_channels_generic, > - _funcs.get_track_copy_permit = get_track_copy_permit_image, > + _funcs.get_track_channels = get_track_channels_generic; > + _funcs.get_track_copy_permit = get_track_copy_permit_image; > _funcs.get_track_format = get_track_format_nrg; > _funcs.get_track_green = _get_track_green_nrg; > _funcs.get_track_lba = NULL; /* Will use generic routine via msf > */ > _funcs.get_track_msf = _get_track_msf_image; > - _funcs.get_track_preemphasis = get_track_preemphasis_generic, > + _funcs.get_track_preemphasis = get_track_preemphasis_generic; > + _funcs.get_track_pregap_lba = get_track_pregap_lba_image; > _funcs.lseek = _lseek_nrg; > _funcs.read = _read_nrg; > _funcs.read_audio_sectors = _read_audio_sectors_nrg; > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image/nrg.h libcdio-0.80/lib/driver/image/nrg.h > --- libcdio-0.80-clean/lib/driver/image/nrg.h 2006-01-14 > 04:45:44.000000000 -0500 > +++ libcdio-0.80/lib/driver/image/nrg.h 2008-03-08 23:16:21.000000000 > -0500 > @@ -71,19 +71,48 @@ > uint32_t lsn GNUC_PACKED; > } _cuex_array_t; > > +/* New DAO[XI] Information from > http://en.wikipedia.org/wiki/NRG_(file_format) > +*/ > + > typedef struct { > - uint32_t _unknown1 GNUC_PACKED; > - char psz_mcn[CDIO_MCN_SIZE]; > - uint8_t _unknown[64-CDIO_MCN_SIZE-sizeof(uint32_t)]; > + uint8_t zero[10]; > + uint32_t sector_size GNUC_PACKED; > + uint8_t unknown[4]; > +} _dao_array_common_t; > + > +typedef struct { > + _dao_array_common_t common; > + uint64_t index0 GNUC_PACKED; > + uint64_t index1 GNUC_PACKED; > + uint64_t end_of_track GNUC_PACKED; > } _daox_array_t; > > typedef struct { > - uint32_t _unknown1 GNUC_PACKED; > - char psz_mcn[CDIO_MCN_SIZE]; > - uint8_t _unknown[64-CDIO_MCN_SIZE-sizeof(uint32_t)]; > + _dao_array_common_t common; > + uint32_t index0 GNUC_PACKED; > + uint32_t index1 GNUC_PACKED; > + uint32_t end_of_track GNUC_PACKED; > } _daoi_array_t; > > typedef struct { > + uint32_t chunk_size_le GNUC_PACKED; > + char psz_mcn[CDIO_MCN_SIZE]; > + uint8_t unknown[3]; > + uint8_t first_track; > + uint8_t last_track; > +} _dao_common_t; > + > +typedef struct { > + _dao_common_t common; > + _daox_array_t track_info[EMPTY_ARRAY_SIZE]; > +} _daox_t; > + > +typedef struct { > + _dao_common_t common; > + _daoi_array_t track_info[EMPTY_ARRAY_SIZE]; > +} _daoi_t; > + > +typedef struct { > uint32_t id GNUC_PACKED; > uint32_t len GNUC_PACKED; > char data[EMPTY_ARRAY_SIZE]; > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image.h libcdio-0.80/lib/driver/image.h > --- libcdio-0.80-clean/lib/driver/image.h 2005-02-16 23:57:21.000000000 > -0500 > +++ libcdio-0.80/lib/driver/image.h 2008-03-10 14:50:01.000000000 -0400 > @@ -48,7 +48,8 @@ > msf_t start_msf; > lba_t start_lba; > int start_index; > - lba_t pregap; /**< pre-gap with zero audio data */ > + lba_t pregap; /**< pre-gap */ > + lba_t silence; /**< pre-gap with zero audio data */ > int sec_count; /**< Number of sectors in this track. Does > not > include pregap */ > int num_indices; > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image_common.c > libcdio-0.80/lib/driver/image_common.c > --- libcdio-0.80-clean/lib/driver/image_common.c 2005-02-17 > 02:03:37.000000000 -0500 > +++ libcdio-0.80/lib/driver/image_common.c 2008-03-10 15:34:08.000000000 > -0400 > @@ -246,6 +246,30 @@ > & PRE_EMPHASIS ) ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE; > } > > +/*! Return the starting LBA for the pregap for track number i_track. > + Track numbers start at 1. > + CDIO_INVALID_LBA is returned on error. > +*/ > +lba_t > +get_track_pregap_lba_image(const void *p_user_data, track_t i_track) > +{ > + const _img_private_t *p_env = p_user_data; > + lba_t pregap, start_lba; > + > + pregap = p_env->tocent[i_track-p_env->gen.i_first_track].pregap; > + start_lba = p_env->tocent[i_track-p_env->gen.i_first_track].start_lba; > + > + /* avoid initializing pregap to CDIO_INVALID_LBA by letting calloc > + do the work. also, nero files have the pregap set equal > + to the start of the track when there is no pregap > + */ > + if (!pregap || pregap == start_lba) { > + pregap = CDIO_INVALID_LBA; > + } > + > + return pregap; > +} > + > /*! > Read a data sector > > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/image_common.h > libcdio-0.80/lib/driver/image_common.h > --- libcdio-0.80-clean/lib/driver/image_common.h 2005-02-17 > 02:03:37.000000000 -0500 > +++ libcdio-0.80/lib/driver/image_common.h 2008-03-09 21:03:31.000000000 > -0400 > @@ -150,6 +150,13 @@ > */ > track_flag_t get_track_preemphasis_image(const void *p_user_data, > track_t i_track); > + > +/*! Return the starting LBA for the pregap for track number i_track. > + Track numbers start at 1. > + CDIO_INVALID_LBA is returned on error. > +*/ > +lba_t get_track_pregap_lba_image(const void *p_user_data, track_t i_track); > + > /*! > Read a data sector > > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/libcdio.sym libcdio-0.80/lib/driver/libcdio.sym > --- libcdio-0.80-clean/lib/driver/libcdio.sym 2007-12-15 > 17:35:53.000000000 -0500 > +++ libcdio-0.80/lib/driver/libcdio.sym 2008-03-10 16:17:27.000000000 > -0400 > @@ -80,6 +80,8 @@ > cdio_get_track_green > cdio_get_track_last_lsn > cdio_get_track_lba > +cdio_get_track_pregap_lba > +cdio_get_track_pregap_lsn > cdio_get_track_lsn > cdio_get_track_msf > cdio_get_track_preemphasis > diff -ur -x libcdio.info -x version.h -x 'libiso9660*pc' -x 'libcdio*pc' > libcdio-0.80-clean/lib/driver/track.c libcdio-0.80/lib/driver/track.c > --- libcdio-0.80-clean/lib/driver/track.c 2005-02-05 23:20:25.000000000 > -0500 > +++ libcdio-0.80/lib/driver/track.c 2008-03-10 16:16:54.000000000 -0400 > @@ -229,7 +229,7 @@ > i_track in cdio. Tracks numbers start at 1. > The "leadout" track is specified either by > using i_track LEADOUT_TRACK or the total tracks+1. > - CDIO_INVALID_LBA is returned on error. > + CDIO_INVALID_LSN is returned on error. > */ > lsn_t > cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track) > @@ -247,6 +247,34 @@ > } > > /*! > + Return the starting LBA for the pregap for track number > + i_track in cdio. Track numbers start at 1. > + CDIO_INVALID_LBA is returned on error. > +*/ > +lba_t > +cdio_get_track_pregap_lba(const CdIo_t *p_cdio, track_t i_track) > +{ > + if (p_cdio == NULL) return CDIO_INVALID_LBA; > + > + if (p_cdio->op.get_track_pregap_lba) { > + return p_cdio->op.get_track_pregap_lba (p_cdio->env, i_track); > + } else { > + return CDIO_INVALID_LBA; > + } > +} > + > +/*! > + Return the starting LSN for the pregap for track number > + i_track in cdio. Track numbers start at 1. > + CDIO_INVALID_LSN is returned on error. > +*/ > +lsn_t > +cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track) > +{ > + return cdio_lba_to_lsn(cdio_get_track_pregap_lba(p_cdio, i_track)); > +} > + > +/*! > Return the ending LSN for track number > i_track in cdio. CDIO_INVALID_LSN is returned on error. > */