[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libcdio-devel] speaking of pre-gap detection....

From: R. Bernstein
Subject: Re: [Libcdio-devel] speaking of pre-gap detection....
Date: Thu, 6 Mar 2008 05:14:55 -0500

Robert William Fuller writes:
 > > Robert William Fuller writes:
 > snip
 > >  > So, we're back to the age old question of how to export this 
 > >  > information.  What is your opinion of the following for an API?
 > >  > 
 > >  > lsn_t cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track);
 > >  > 
 > >  > I would have it return CDIO_INVALID_LSN if the data isn't available.
 > >  > 
 > >  > Thoughts, questions, concerns?
 > > 
 > > I'm cool with this. What do others think?
 > I have been thinking about this.  A more general interface would look 
 > like this:
 > lsn_t cdio_get_track_index_lsn(const CdIo_t *p_cdio, track_t i_track, 
 > int index);
 > Hence, to get the "pregap" which is index 0 in the Q sub-channel, you 
 > would use cdio_get_track_index_lsn(cdio, trackno, 0);
 > I think this would be better because it is one interface that 
 > accommodates both pregap (index 0) and the other 99 possible per-track 
 > indices, although initially I would probably only support index 0 for 
 > the image drivers.

I like it. Also there is a post-gap. From an old PDF of a draft of the
MMC-3 commands in the section describing the command "SEND CUE SHEET"
(5.29) Pre-gap If a Data track is preceded by a different mode of
track (such as an audio track) or if the mode number of CD-ROM
changes, this Data track starts with an extended pre-gap. A pre-gap is
placed at the head of a Data track, also is belonging to the Data
track. A pre-gap does not contain actual user data. The pre-gap is
encoded as "pause".

An extended pre-gap is divided into two parts. The first part of the
extended pre-gap has a minimum 1 second of data, and it is encoded
according to the data structure of previous track. The second part has
a minimum 2 seconds data, and this data track is encoded according to
the same data structure as the other parts. Post-gap 

If a Data track is followed by another kind of track (such as an audio
track), this Data track ends with a post-gap. A post-gap is placed at
the end of a Data track, and is part of the Data Track. A post-gap
does not contain actual user data. The minimum length of post-gap is 2
seconds. The Logical Unit does not perform any action for a Post-gap.

 > it comes from the cue sheet or toc file's "PREGAP" keyword.  While it 
 > does mean index 0, it additionally implies silence.  Curiously, it is 
 > never used beyond setting it.  

I think the idea was that one could/should be able to query what the
value is presumably like one can do on a real CD, but that interface
just hasn't been done since it never was needed/requested.

 > I thought about co-opting this field so 
 > as not to change the ABI, but I'm not sure what is usually done?

As you note later, all of this is internal, and I think even changes
with the driver.

 > In the interest of keeping things simple, cued uses this data structure 
 > to store indices:
 > lsn_t rip_indices[ CDIO_CD_MAX_TRACKS + 1 ][ CUED_MAX_INDICES ];
 > Note that this is about 40K in size.  I'm not sure about the memory 
 > constraints for libcdio, so I have some misgivings about using a similar 
 > structure in libcdio.  What are your thoughts?

40K isn't so bad, but on the other hand most of this space would not
be used. A more space efficent structure which I don't think is so
awkward would and whose access time would be pretty fast given the
data is sparse, be the way old list of lists idea (from say Aho,
Hopcroft and Ulman although no doubt it precedes that).  Have a list
with of (index, value) pairs that is malloc's or calloc'd.  For

rip_index_pairs (size malloc'd to need).
typedef struct  {
  index_t index_number; /* "i" below */
  lsn_t   value;        /* "v" below */
} rip_index_pair_t;

rip_index_pair_t *rip_index_head[100];

Some example data for 3 tracks which have an index 0. Track 1 also has
a 1 index at lsn 300.

/*  i, v */
0: [0, 150]  /* Track 1 starts here */
1: [1, 300]
2: [0, 350]  /* Track 2 starts here */
3: [0, 410]  /* Track 3 starts here */

                  /* 1, 2, ... 99 */
rip_index_head[*] = [0, 2, 3]

Instead of rip_indices[track, index] one could write an (inline?)
function, e.g. get_rip_indices(track, index) which retrieves the value
by starting at rip_index_head[track] and scans unitl
rip_index_head[track+1] for "index".

reply via email to

[Prev in Thread] Current Thread [Next in Thread]