|
Packit |
dd8086 |
\input texinfo @c -*-texinfo-*-
|
|
Packit |
dd8086 |
@c %**start of header
|
|
Packit |
dd8086 |
@setfilename libcdio.info
|
|
Packit |
dd8086 |
@include version.texi
|
|
Packit |
dd8086 |
@settitle GNU @code{libcdio}: Compact Disc Input, Output, and Control Library
|
|
Packit |
dd8086 |
@c %**end of header
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@c Karl Berry informs me that this will add straight quotes in
|
|
Packit |
dd8086 |
@c typewriter text.
|
|
Packit |
dd8086 |
@c See the "Inserting Quote Characters" node in the Texinfo manual
|
|
Packit |
dd8086 |
@set txicodequoteundirected
|
|
Packit |
dd8086 |
@set txicodequotebacktick
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@copying
|
|
Packit |
dd8086 |
This manual documents @code{libcdio}, the GNU CD Input, Output, and Control
|
|
Packit |
dd8086 |
Library.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Copyright @copyright{} 2003-2008, 2010, 2012-2014 Rocky
|
|
Packit |
dd8086 |
Bernstein and Herbert Valerio Riedel.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@quotation
|
|
Packit |
dd8086 |
Permission is granted to copy, distribute and/or modify this document
|
|
Packit |
dd8086 |
under the terms of the GNU Free Documentation License, Version 1.2 or
|
|
Packit |
dd8086 |
any later version published by the Free Software Foundation; with no
|
|
Packit |
dd8086 |
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
|
Packit |
dd8086 |
Texts. A copy of the license is included in the section entitled
|
|
Packit |
dd8086 |
``GNU Free Documentation License''.
|
|
Packit |
dd8086 |
@end quotation
|
|
Packit |
dd8086 |
@end copying
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@paragraphindent 0
|
|
Packit |
dd8086 |
@exampleindent 0
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@set libcdio @code{libcdio}
|
|
Packit |
dd8086 |
@set program @kbd{libcdio}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@c A macro for defining terms variables.
|
|
Packit |
dd8086 |
@macro term{varname}
|
|
Packit |
dd8086 |
@c @cindex{\varname\}
|
|
Packit |
dd8086 |
@emph{\varname\}
|
|
Packit |
dd8086 |
@end macro
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@dircategory Software libraries
|
|
Packit |
dd8086 |
@direntry
|
|
Packit |
dd8086 |
* libcdio: (libcdio). GNU Compact Disc Input, Output, and Control Library.
|
|
Packit |
dd8086 |
@end direntry
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@titlepage
|
|
Packit |
dd8086 |
@title GNU @code{libcdio}
|
|
Packit |
dd8086 |
@subtitle GNU Compact Disc Input, Output, and Control Library
|
|
Packit |
dd8086 |
@subtitle for version @value{VERSION}, @value{UPDATED}
|
|
Packit |
dd8086 |
@author Rocky Bernstein et al. (@email{bug-libcdio@@gnu.org})
|
|
Packit |
dd8086 |
@page
|
|
Packit |
dd8086 |
@vskip 0pt plus 1filll
|
|
Packit |
dd8086 |
@insertcopying
|
|
Packit |
dd8086 |
@end titlepage
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@contents
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@ifnottex
|
|
Packit |
dd8086 |
@node Top
|
|
Packit |
dd8086 |
@top GNU @value{libcdio}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@insertcopying
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* History:: How this came about
|
|
Packit |
dd8086 |
* Previous Work:: The problem and previous work
|
|
Packit |
dd8086 |
* Purpose:: What is in this package (and what's not)
|
|
Packit |
dd8086 |
* CD Formats:: A tour through the CD-specification spectrum
|
|
Packit |
dd8086 |
* CD Image Formats:: A tour through various CD-image formats
|
|
Packit |
dd8086 |
* CD Units:: The units that make up a CD
|
|
Packit |
dd8086 |
* How to use:: Okay enough babble, lemme at the library!
|
|
Packit |
dd8086 |
* Utility Programs:: Diagnostic programs that come with this library
|
|
Packit |
dd8086 |
* CD-ROM Access and Drivers:: CD-ROM access and drivers
|
|
Packit |
dd8086 |
* Internal Program Organization:: Looking under the hood
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Appendices
|
|
Packit |
dd8086 |
* ISO-9660 Character Sets::
|
|
Packit |
dd8086 |
* Glossary::
|
|
Packit |
dd8086 |
* GNU Free Documentation License::
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Indices
|
|
Packit |
dd8086 |
* General Index:: Overall index
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
@end ifnottex
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node History
|
|
Packit |
dd8086 |
@chapter History
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
As a result of the repressive Digital Millennium Copyright Act, DMCA,
|
|
Packit |
dd8086 |
I became aware of Video CD's (VCD's). Video CD's are not subject to
|
|
Packit |
dd8086 |
the DMCA and therefore enjoy the protection afforded by copyright but
|
|
Packit |
dd8086 |
no more. But in order for VCD's to be competitive with DVD's, good
|
|
Packit |
dd8086 |
tools -- including GPL tools -- are needed for authoring and playing
|
|
Packit |
dd8086 |
them. And so through VCD's I became aware of the excellent Video CD
|
|
Packit |
dd8086 |
tools by Herbert Valerio Riedel which form the @kbd{vcdimager}
|
|
Packit |
dd8086 |
package.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Although vcdimager is great for authoring, examining and extracting
|
|
Packit |
dd8086 |
parts of a Video CD, it is not a VCD player. And when I looked at the
|
|
Packit |
dd8086 |
state of Video CD handling in existing VCD players: @code{xine},
|
|
Packit |
dd8086 |
@code{MPlayer}, and @code{vlc}, I was a bit disappointed. None handled
|
|
Packit |
dd8086 |
playback control, menu selections, or playing still frames and
|
|
Packit |
dd8086 |
segments from track 1.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Version 0.7.12 of vcdimager was very impressive, however it lacked
|
|
Packit |
dd8086 |
exportable libraries that could be used in other projects. So with the
|
|
Packit |
dd8086 |
blessing and encouragement of Herbert Valerio Riedel, I took to
|
|
Packit |
dd8086 |
extract and create libraries from this code base. The result was two
|
|
Packit |
dd8086 |
libraries: one to extract information from a VCD which I called
|
|
Packit |
dd8086 |
libvcdinfo, and another to do the reading and control of a VCD. Well,
|
|
Packit |
dd8086 |
actually, at this point I should say that a Video CD is really just
|
|
Packit |
dd8086 |
Video put on a existing well-established Compact Disc or CD format. So
|
|
Packit |
dd8086 |
the library for this is called @value{libcdio} rather than
|
|
Packit |
dd8086 |
@kbd{libvcdio}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
While on the topic of the name @value{libcdio}, I should also explain that
|
|
Packit |
dd8086 |
the library really doesn't handle writing or output (the final "o" in
|
|
Packit |
dd8086 |
the name). However it was felt that if I put @code{libcdi} that might be
|
|
Packit |
dd8086 |
confused with a particular CD format called CD-I.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Later on, the ISO-9660 filesystem handling component from
|
|
Packit |
dd8086 |
@kbd{vcdimager} was extracted, expanded and made a separate
|
|
Packit |
dd8086 |
library. Next the ability to add MMC commands was added, and then
|
|
Packit |
dd8086 |
CD paranoia support. And from there, the rest is history.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Previous Work
|
|
Packit |
dd8086 |
@chapter The problem and previous work
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If around the year 2002 you were to look at the code for a number of
|
|
Packit |
dd8086 |
free software CD or media players that work on several platforms such as
|
|
Packit |
dd8086 |
vlc, MPlayer, xine, or xmms to name but a few, you'd find the code to
|
|
Packit |
dd8086 |
read a CD sprinkled with conditional compilation for this or that
|
|
Packit |
dd8086 |
platform. That is there was @emph{no} OS-independent programmer
|
|
Packit |
dd8086 |
library for CD reading and control even though the technology was over
|
|
Packit |
dd8086 |
10 years old; yet there are media players which strive for OS
|
|
Packit |
dd8086 |
independence.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
One early CD player, @kbd{xmcd} by Ti Kan, was I think a bit better
|
|
Packit |
dd8086 |
than most in that it tried to @emph{encapsulate} the kinds of CD
|
|
Packit |
dd8086 |
control mechanisms, e.g.\ SCSI, Linux ioctl, Toshiba, in a "CD Audio
|
|
Packit |
dd8086 |
Device Interface Library" called @code{libdi}. However this library is for
|
|
Packit |
dd8086 |
Audio CD's only and I don't believe this library has been used outside
|
|
Packit |
dd8086 |
of xmcd.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another project, Simple DirectMedia Layer also encapsulates CD
|
|
Packit |
dd8086 |
reading.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@quotation
|
|
Packit |
dd8086 |
SDL is a library that allows you portable low-level access to a video
|
|
Packit |
dd8086 |
framebuffer, audio output, mouse, and keyboard. With SDL, it is easy
|
|
Packit |
dd8086 |
to write portable games which run on ...
|
|
Packit |
dd8086 |
@end quotation
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Many of the media players mentioned above do in fact can make use of
|
|
Packit |
dd8086 |
the SDL library but for @emph{video} output only. Because the encapsulation
|
|
Packit |
dd8086 |
is over @emph{many} kinds of I/O (video, joysticks, mice, as well as CD's),
|
|
Packit |
dd8086 |
I believe that the level of control provided for CD a little bit
|
|
Packit |
dd8086 |
limited. (However to be fair, it may have only been intended for games
|
|
Packit |
dd8086 |
and may be suitable for that). Applications that just want the CD
|
|
Packit |
dd8086 |
reading and control portion I think will find quite a bit overhead.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another related project is J@"org Schilling's SCSI library. You can
|
|
Packit |
dd8086 |
use that to make a non-SCSI CD-ROM act like one that understands SCSI
|
|
Packit |
dd8086 |
MMC commands which is a neat thing to do. However it is a little weird
|
|
Packit |
dd8086 |
to have to install drivers just so you can run a particular user-level
|
|
Packit |
dd8086 |
program. Installing drivers often requires special privileges and
|
|
Packit |
dd8086 |
permissions and it is pervasive on a system. It is a little sad that
|
|
Packit |
dd8086 |
along the way to creating such a SCSI library a library similar to
|
|
Packit |
dd8086 |
@value{libcdio} wasn't created which could be used. Were that the
|
|
Packit |
dd8086 |
case, this library certainly never would have been written.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
At the OS level there is the ``A Linux CD-ROM Standard'' by David van
|
|
Packit |
dd8086 |
Leeuwen from around 1999. This defines a set of definitions and
|
|
Packit |
dd8086 |
ioctl's that mask hardware differences of various Compact Disc
|
|
Packit |
dd8086 |
hardware. It is a great idea, however this ``standard'' lacked
|
|
Packit |
dd8086 |
adoption on OS's other than GNU/Linux. Or maybe it's the case that the
|
|
Packit |
dd8086 |
standard on other OS's lacked adoption on GNU/Linux. For example on
|
|
Packit |
dd8086 |
FreeBSD there is a ``Common Access Method'' (CAM) used for all SCSI
|
|
Packit |
dd8086 |
access which seems not to be adopted in GNU/Linux.@footnote{And I'm
|
|
Packit |
dd8086 |
thankful for that since, at least for MMC commands, it is
|
|
Packit |
dd8086 |
inordinately complicated and in some places arcane.}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Finally at the hardware level where a similar chaos exists, there has
|
|
Packit |
dd8086 |
been an attempt to do something similar with the MMC (multimedia
|
|
Packit |
dd8086 |
commands). This attempts to provide a uniform command set for CD
|
|
Packit |
dd8086 |
devices like PostScript does for printer commands.@footnote{I wrote
|
|
Packit |
dd8086 |
``attempts'' because over time the command set has changed and now
|
|
Packit |
dd8086 |
there are several different commands to do a particular function like
|
|
Packit |
dd8086 |
read a CD table of contents and some hardware understands some of the
|
|
Packit |
dd8086 |
version of the commands set but might not others} In contrast to
|
|
Packit |
dd8086 |
PostScript where there one in theory can write a PostScript program in
|
|
Packit |
dd8086 |
a uniform ASCII representation and send that to a printer, for MMC
|
|
Packit |
dd8086 |
although there are common internal structures defined, there is no
|
|
Packit |
dd8086 |
common syntax for representing the structures or an OS-independent
|
|
Packit |
dd8086 |
library or API for issuing MMC-commands which a programmer would need
|
|
Packit |
dd8086 |
to use. Instead each Operating System has its own interface. For
|
|
Packit |
dd8086 |
example Adaptec's ASPI or Microsoft's DeviceIoControl on Microsoft
|
|
Packit |
dd8086 |
Windows, or IOKit for Apple's OS/X, or FreeBSD's CAM. I've been
|
|
Packit |
dd8086 |
positively awed at how many different variations and differing levels
|
|
Packit |
dd8086 |
of complexity there are for doing basically the same thing. How easy
|
|
Packit |
dd8086 |
it is to issue an MMC command from a program varies from easy to very
|
|
Packit |
dd8086 |
difficult. And mastering the boilerplate code to issue an MMC command
|
|
Packit |
dd8086 |
on one OS really doesn't help much in figuring out how to do it on
|
|
Packit |
dd8086 |
another OS. So in @value{libcdio} we provide a common (and hopefully
|
|
Packit |
dd8086 |
simple) API to issue MMC commands.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Purpose
|
|
Packit |
dd8086 |
@chapter What is in this package (and what's not)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The library, @command{libcdio}, encapsulates CD-ROM reading and
|
|
Packit |
dd8086 |
control. Applications wishing to be oblivious of the OS- and
|
|
Packit |
dd8086 |
device-dependent properties of a CD-ROM can use this library.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Also included is a library, @command{libiso9660}, for working with
|
|
Packit |
dd8086 |
ISO-9660 filesystems.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Some support for disk-image types like cdrdao's TOC, CDRWIN's BIN/CUE
|
|
Packit |
dd8086 |
and Ahead Nero's NRG format is available, so applications that use this
|
|
Packit |
dd8086 |
library also have the ability to read disc images as though they were
|
|
Packit |
dd8086 |
CDs.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@command{libcdio} also provides a way to issue SCSI ``MultiMedia
|
|
Packit |
dd8086 |
Commands'', MMC. MMC is supported by many hardware CD-ROM
|
|
Packit |
dd8086 |
manufacturers; and in some cases where a CD-ROM doesn't understand MMC
|
|
Packit |
dd8086 |
directly, some Operating Systems (such as GNU/Linux, Solaris, or
|
|
Packit |
dd8086 |
FreeBSD or Microsoft Windows ASPI to name a few) provide the MMC
|
|
Packit |
dd8086 |
emulation.@footnote{This concept of software emulation of a common
|
|
Packit |
dd8086 |
hardware command language is common for printers such as using
|
|
Packit |
dd8086 |
ghostscript to private postscript emulation for a non-postscript
|
|
Packit |
dd8086 |
printer.}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
As a separate package under a separate GPL2 license are
|
|
Packit |
dd8086 |
@command{libcdio_paranoia}, and @command{libcdio_cdda} libraries for
|
|
Packit |
dd8086 |
applications which want to use cdparanoia's error-correction and
|
|
Packit |
dd8086 |
jitter detection.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The first use of the library in this package are the Video CD
|
|
Packit |
dd8086 |
authoring and ripping tools, VCDImager
|
|
Packit |
dd8086 |
(@url{http://vcdimager.org}). See
|
|
Packit |
dd8086 |
@url{http://www.gnu.org/software/libcdio/projects.html} for a list of
|
|
Packit |
dd8086 |
projects using @command{libcdio}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A version of the CD-DA extraction tool cdparanoia,
|
|
Packit |
dd8086 |
@url{http://www.xiph.org/paranoia}, and its library which corrects
|
|
Packit |
dd8086 |
for CD-ROM jitter are part of the distribution.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Also included in the libcdio package is a utility program
|
|
Packit |
dd8086 |
@command{cd-info} which displays CD information: number of tracks,
|
|
Packit |
dd8086 |
CD-format and if possible basic information about the format. If
|
|
Packit |
dd8086 |
libcddb (@url{http://libcddb.sourceforge.net}) is available, the
|
|
Packit |
dd8086 |
@command{cd-info} program will display CDDB matches on CD-DA
|
|
Packit |
dd8086 |
discs. And if a new enough version of libvcdinfo is available from
|
|
Packit |
dd8086 |
the vcdimager project, then @command{cd-info} shows basic VCD
|
|
Packit |
dd8086 |
information.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Other utility programs in the libcdio package are:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@table @code
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{cdda-player}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
shows off @value{libcdio} audio and CD-ROM control commands. It can
|
|
Packit |
dd8086 |
play a track, eject or load media and show the the status of a CD-DA
|
|
Packit |
dd8086 |
that is might be currently played via the audio control commands. It
|
|
Packit |
dd8086 |
can be run in batch mode or has a simple curses-based interface.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If libcddb is available or a CD has CD-Text and your CD-ROM drive
|
|
Packit |
dd8086 |
supports CD-Text, track/album information about the CD can be shown.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{cd-drive}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
shows what drivers are available and some basic properties of
|
|
Packit |
dd8086 |
cd-drives attached to the system. Media may have to be inserted
|
|
Packit |
dd8086 |
in order to get this info. The program also lists out drive capabilities
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item cd-read
|
|
Packit |
dd8086 |
performs low-level block reading of a CD or CD image
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{iso-info}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
displays ISO-9660 information from an ISO-9660 image. Below is some
|
|
Packit |
dd8086 |
sample output
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
iso-info version 0.82 x86_64-unknown-linux-gnu
|
|
Packit |
dd8086 |
Copyright (c) 2003, 2004, 2005, 2007, 2008 R. Bernstein
|
|
Packit |
dd8086 |
This is free software; see the source for copying conditions.
|
|
Packit |
dd8086 |
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
|
Packit |
dd8086 |
PARTICULAR PURPOSE.
|
|
Packit |
dd8086 |
__________________________________
|
|
Packit |
dd8086 |
ISO 9660 image: ../test/joliet.iso
|
|
Packit |
dd8086 |
Application: K3B THE CD KREATOR VERSION 0.11.12 (C) 2003 SEBASTIAN TRUEG AND...
|
|
Packit |
dd8086 |
Preparer : K3b - Version 0.11.12
|
|
Packit |
dd8086 |
Publisher : Rocky Bernstein
|
|
Packit |
dd8086 |
System : LINUX
|
|
Packit |
dd8086 |
Volume : K3b data project
|
|
Packit |
dd8086 |
Volume Set :
|
|
Packit |
dd8086 |
__________________________________
|
|
Packit |
dd8086 |
ISO-9660 Information
|
|
Packit |
dd8086 |
/:
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 .
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 ..
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 libcdio
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/libcdio/:
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 .
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 ..
|
|
Packit |
dd8086 |
Mar 12 2004 02:18 COPYING
|
|
Packit |
dd8086 |
Jun 26 2004 07:01 README
|
|
Packit |
dd8086 |
Aug 12 2004 06:22 README.libcdio
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 test
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/libcdio/test/:
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 .
|
|
Packit |
dd8086 |
Oct 22 2004 19:44 ..
|
|
Packit |
dd8086 |
Jul 25 2004 06:52 isofs-m1.cue
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{iso-read}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
extracts files from an ISO-9660 image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{mmc-tool}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
a program for issuing some MMC commands
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end table
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Historically, @code{libcdio} did not support write access to
|
|
Packit |
dd8086 |
drives. In conjunction with additional work in a separate project
|
|
Packit |
dd8086 |
@code{libburn}, Thomas Schmitt has modified @code{libcdio} to enable
|
|
Packit |
dd8086 |
sending SCSI write commands on some of the drivers. This enables other
|
|
Packit |
dd8086 |
programs like @code{libburn} to write to CD's, DVD's and Blu-Ray
|
|
Packit |
dd8086 |
discs.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For the OS drivers which are lacking write access, volunteers are
|
|
Packit |
dd8086 |
welcome.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CD Formats
|
|
Packit |
dd8086 |
@chapter CD Formats
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Much of what I write in this section can be found elsewhere. See for
|
|
Packit |
dd8086 |
example @url{http://www.pctechguide.com/08cd-rom.htm} or
|
|
Packit |
dd8086 |
@url{http://www.pcguide.com/ref/cd/format.htm}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
We give just enough background here to cover Compact Discs and Compact
|
|
Packit |
dd8086 |
Disc formats that are handled by this library.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The Sony and Philips Corporations invented and Compact Disc (CD) in
|
|
Packit |
dd8086 |
the early 1980s. The specifications for the layout is often referred
|
|
Packit |
dd8086 |
to by the color of the cover on the specification.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* Red Book:: Red Book (CD-DA) CD Text, CDDB
|
|
Packit |
dd8086 |
* Yellow Book:: Yellow Book (CD-ROM Digital Data)
|
|
Packit |
dd8086 |
* Green Book:: Green Book (CD-i)
|
|
Packit |
dd8086 |
* White Book:: White Book (DV, Video CD)
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Red Book
|
|
Packit |
dd8086 |
@section Red Book (CD-DA)
|
|
Packit |
dd8086 |
@cindex Red Book
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* CD Text:: CD Text and CD+G
|
|
Packit |
dd8086 |
* CDDB:: Internet CD Database (CDDB)
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The first type of CD that was produced was the Compact Disc Digital
|
|
Packit |
dd8086 |
Audio (CD-DA) or just plain ``audio CD''. The specification, ICE 60908
|
|
Packit |
dd8086 |
(formerly IEC 908) is commonly called the ``Red Book'',
|
|
Packit |
dd8086 |
@cite{@url{http://en.wikipedia.org/wiki/Red_Book_(audio_CD_standard)}}. Music
|
|
Packit |
dd8086 |
CD's are recorded in this format which basically allows for around 74
|
|
Packit |
dd8086 |
minutes of audio per disc and for that information to be split up into
|
|
Packit |
dd8086 |
tracks. Tracks are broken up into "sectors" and each sector contains
|
|
Packit |
dd8086 |
up to 2,352 bytes. To play one 44.1 kHz CD-DA sampled audio second, 75
|
|
Packit |
dd8086 |
sectors are used.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The minute/second/frame numbering of sectors or MSF format is based on
|
|
Packit |
dd8086 |
the fact that 75 sectors are used in a second of playing of
|
|
Packit |
dd8086 |
sound. (And for almost every other CD format and application the MSF
|
|
Packit |
dd8086 |
format doesn't make that much sense).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In @value{libcdio} when you you want to read an audio sector, you call
|
|
Packit |
dd8086 |
@code{cdio_read_audio_sector()} or @code{cdio_read_audio_sectors()}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@cindex subchannel
|
|
Packit |
dd8086 |
In addition the the audio data ``channel'' a provision for other
|
|
Packit |
dd8086 |
information or @term{subchannel} information) can be stored in a
|
|
Packit |
dd8086 |
sector. Other subchannels include a Media Catalog Number (also
|
|
Packit |
dd8086 |
abbreviated as MCN and sometimes a UPC), or album meta data (also
|
|
Packit |
dd8086 |
called CD-Text). Karioke graphics can also be stored in a format
|
|
Packit |
dd8086 |
called @term{CD+G}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CD Text
|
|
Packit |
dd8086 |
@subsection CD Text, CD+G
|
|
Packit |
dd8086 |
@cindex CD Text
|
|
Packit |
dd8086 |
@cindex CD+G
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
CD Text is an extension to the CD-DA standard that adds the ability to
|
|
Packit |
dd8086 |
album and track meta data (titles, artist/performer names, song
|
|
Packit |
dd8086 |
titles) and graphical (e.g. Karaoke) information. For an
|
|
Packit |
dd8086 |
alternative way to get album and track meta-data see @xref{CDDB}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Information is stored in such a way that it doesn't interfere with the
|
|
Packit |
dd8086 |
normal operation of any CD players or CDROM drives. There are two
|
|
Packit |
dd8086 |
different parts of the CD where the data can be stored.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The first place the information can be recorded is in the R-W sub
|
|
Packit |
dd8086 |
codes in the lead in area of the CD. This information is stored as a
|
|
Packit |
dd8086 |
single block of data and is the format. The method for reading this
|
|
Packit |
dd8086 |
data from a CDROM drive is covered under the Sony proposal to the MMC
|
|
Packit |
dd8086 |
specification. The format of the data is partially covered in the MMC
|
|
Packit |
dd8086 |
specification.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
CD Text information is stored in this area. The format that follows
|
|
Packit |
dd8086 |
the Interactive Text Transmission System (ITTS) is the same data
|
|
Packit |
dd8086 |
transmission standard used by such things as Digital Audio
|
|
Packit |
dd8086 |
Broadcasting (DAB), and virtually the same as the data standard for
|
|
Packit |
dd8086 |
the MiniDisc.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The second place the information can be recorded is in the R-W sub
|
|
Packit |
dd8086 |
codes in the program area of the CD giving a data capacity of roughly
|
|
Packit |
dd8086 |
31MB. CD+G (CD w/graphics) uses this method.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The methods for reading this data from a CD-ROM drive were first
|
|
Packit |
dd8086 |
covered by the programming specs from the individual drive
|
|
Packit |
dd8086 |
manufacturers. In the case of ATAPI drives, the SFF8020 spec covers
|
|
Packit |
dd8086 |
the reading of the RW subcodes. Subsequently it has been encorporated
|
|
Packit |
dd8086 |
into the MMC specifications.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Not all drives support reading the RW subcodes from the program
|
|
Packit |
dd8086 |
area. However for those that do, @value{libcdio} provides a way to get
|
|
Packit |
dd8086 |
at this information via @code{cdtext_get()} and its friends.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There is a separate document in this distribution describing CD-Text
|
|
Packit |
dd8086 |
information and how it is encoded.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CDDB
|
|
Packit |
dd8086 |
@subsection Internet CD Database (CDDB)
|
|
Packit |
dd8086 |
@cindex CDDB
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
CDDB is an database on the Internet of of CD album/track, artist, and
|
|
Packit |
dd8086 |
genre information similar to CD Text information. Using track
|
|
Packit |
dd8086 |
information (number of tracks and length of the tracks), devices that
|
|
Packit |
dd8086 |
have access to the Internet can query for meta information and
|
|
Packit |
dd8086 |
contribute information for CD's where there is no existing
|
|
Packit |
dd8086 |
information. When storage is available (such as you'd expect for any
|
|
Packit |
dd8086 |
program using @value{libcdio}, the information is often saved for
|
|
Packit |
dd8086 |
later use when the Internet is not available; people tend request the
|
|
Packit |
dd8086 |
same information since they via programs play the same music.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Obtaining CD meta information when none is encoded in an audio CD is
|
|
Packit |
dd8086 |
useful in media players or making ones own compilations from audio
|
|
Packit |
dd8086 |
CDs.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There are currently two popular CDDB services on the Internet. The
|
|
Packit |
dd8086 |
original database has been renamed Gracenote and is a profit making
|
|
Packit |
dd8086 |
entity. FreeDB (@url{http://freedb.org} is an open source CD
|
|
Packit |
dd8086 |
information resource that is free for developers and the public to
|
|
Packit |
dd8086 |
use.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
As there already is an excellent library for handling CDDB libcddb
|
|
Packit |
dd8086 |
(@url{http://libcddb.sourceforge.net} we suggest using that. Our
|
|
Packit |
dd8086 |
utility program @command{cd-info} will make use it if it is available
|
|
Packit |
dd8086 |
and it's what we use in our applications that need it.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Yellow Book
|
|
Packit |
dd8086 |
@section Yellow Book (CD-ROM Digital Data)
|
|
Packit |
dd8086 |
The CD-ROM specification or the ``Yellow Book'' followed a few years
|
|
Packit |
dd8086 |
later (Standards ISO/IEC 10149), and describes the extension of CD's
|
|
Packit |
dd8086 |
to store computer data, i.e. CD-ROM (Compact Disk Read Only Memory).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The specification in the Yellow Book defines two modes: Mode 1 and
|
|
Packit |
dd8086 |
Mode 2.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* ISO 9660::
|
|
Packit |
dd8086 |
* Mode 1:: Mode 1 Format
|
|
Packit |
dd8086 |
* Mode 2:: Mode 2 Format
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO 9660
|
|
Packit |
dd8086 |
@subsection ISO 9660
|
|
Packit |
dd8086 |
@cindex ISO 9660
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* ISO 9660 Level 1::
|
|
Packit |
dd8086 |
* ISO 9660 Level 2::
|
|
Packit |
dd8086 |
* ISO 9660 Level 3::
|
|
Packit |
dd8086 |
* Joliet Extensions::
|
|
Packit |
dd8086 |
* Rock Ridge Extensions::
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The Yellow Book doesn't specify how data is to be stored on a CD-ROM.
|
|
Packit |
dd8086 |
It was feared that different companies would implement proprietary
|
|
Packit |
dd8086 |
data storage formats using this specification, resulting in
|
|
Packit |
dd8086 |
incompatible data CDs. To prevent this, representatives of major
|
|
Packit |
dd8086 |
manufacturers met at the High Sierra Hotel and Casino in Lake Tahoe,
|
|
Packit |
dd8086 |
NV, in 1985, to define a standard for storing data on CDs. This format
|
|
Packit |
dd8086 |
was nicknamed High Sierra Format. In a slightly modified form it was
|
|
Packit |
dd8086 |
later adopted as ISO the ISO 9660 standard. This standard is further
|
|
Packit |
dd8086 |
broken down into 3 "levels", the higher the level, the more
|
|
Packit |
dd8086 |
permissive.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO 9660 Level 1
|
|
Packit |
dd8086 |
@subsubsection ISO 9660 Level 1
|
|
Packit |
dd8086 |
Level 1 ISO 9660 defines names in the 8+3 convention so familiar to
|
|
Packit |
dd8086 |
MS-DOS: eight characters for the filename, a period, and then three
|
|
Packit |
dd8086 |
characters for the file type, all in upper case. The allowed
|
|
Packit |
dd8086 |
characters are A-Z, 0-9, ".", and "_".Level 1 ISO 9660 requires that
|
|
Packit |
dd8086 |
files occupy a contiguous range of sectors. This allows a file to be
|
|
Packit |
dd8086 |
specified with a start block and a count. The maximum directory depth
|
|
Packit |
dd8086 |
is 8. For a table of the characters, see @xref{ISO-9660 Character
|
|
Packit |
dd8086 |
Sets}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO 9660 Level 2
|
|
Packit |
dd8086 |
@subsubsection ISO 9660 Level 2
|
|
Packit |
dd8086 |
Level 2 ISO 9660 allows far more flexibility in filenames, but isn't
|
|
Packit |
dd8086 |
usable on some systems, notably MS-DOS.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO 9660 Level 3
|
|
Packit |
dd8086 |
@subsubsection ISO 9660 Level 3
|
|
Packit |
dd8086 |
Level 3 ISO-9660 allows non-contiguous files, useful if the file was
|
|
Packit |
dd8086 |
written in multiple packets with packet-writing software.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There have been a number of extensions to the ISO 9660 CD-ROM file
|
|
Packit |
dd8086 |
format. One extension is Microsoft's Joliet specification, designed to
|
|
Packit |
dd8086 |
resolve a number of deficiencies in the original ISO 9660 Level 1 file
|
|
Packit |
dd8086 |
system, and in particular to support the long file names used in
|
|
Packit |
dd8086 |
Windows 95 and subsequent versions of Windows.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another extension is the Rock Ridge Interchange Protocol (RRIP), which
|
|
Packit |
dd8086 |
enables the recording of sufficient information to support POSIX File
|
|
Packit |
dd8086 |
System semantics.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Joliet Extensions
|
|
Packit |
dd8086 |
@subsubsection Joliet Extensions
|
|
Packit |
dd8086 |
@cindex Joliet extensions
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Joliet extensions were an upward-compatible extension to the ISO 9660
|
|
Packit |
dd8086 |
specification that removes the limitation initially put in to deal
|
|
Packit |
dd8086 |
with the limited filename conventions found in Microsoft DOS OS. In
|
|
Packit |
dd8086 |
particular, the Joliet specification allows for long filenames and
|
|
Packit |
dd8086 |
allows for UCS-BE (BigEndian Unicode) encoding of filenames which
|
|
Packit |
dd8086 |
include mixed case letter, accented characters spaces and various
|
|
Packit |
dd8086 |
symbols.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The way all of this is encoded is by adding a second directory and
|
|
Packit |
dd8086 |
filesystem structure in addition to or in parallels to original ISO
|
|
Packit |
dd8086 |
9600 filesystem. The root node of the ISO 9660 filesystem is found via
|
|
Packit |
dd8086 |
the @term{Primary Volume Descriptor} or @term{PVD}. The root of the
|
|
Packit |
dd8086 |
Joliet-encode filesystem is found in a Supplementary Volume
|
|
Packit |
dd8086 |
Descriptor or @term{SVD} defined in the ISO 9660 specification. The
|
|
Packit |
dd8086 |
SVD structure is almost identical to a PVD with a couple of unused
|
|
Packit |
dd8086 |
fields getting used and with the filename encoding changed to UCS-BE.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Rock Ridge Extensions
|
|
Packit |
dd8086 |
@subsubsection Rock Ridge Extensions
|
|
Packit |
dd8086 |
@cindex Rock Ridge extensions
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Using the Joliet Extension one overcome the limitedness of the
|
|
Packit |
dd8086 |
original ISO-9660 naming scheme. But another and probably better
|
|
Packit |
dd8086 |
method is to use the Rock Ridge Extension. Not only can one store a
|
|
Packit |
dd8086 |
filename as one does in a POSIX OS, but the other file attributes,
|
|
Packit |
dd8086 |
such as the various timestamps (creation, modification, access), file
|
|
Packit |
dd8086 |
attributes (user, group, file mode permissions, device type, symbolic
|
|
Packit |
dd8086 |
links) can be stored. This is much as one would do in XA attributes;
|
|
Packit |
dd8086 |
however the two are not completely interchangeable in the information
|
|
Packit |
dd8086 |
they store: XA does @emph{not} address filename limitations, and the
|
|
Packit |
dd8086 |
Rock Ridge extensions don't indicate if a sector is in Mode 1 or Mode
|
|
Packit |
dd8086 |
2 format.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The Rock Ridge extension makes use of a hook that was defined as part
|
|
Packit |
dd8086 |
of the ISO 9660 standard.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Mode 1
|
|
Packit |
dd8086 |
@subsection Mode 1 (2048 data bytes per sector)
|
|
Packit |
dd8086 |
@cindex Mode 1
|
|
Packit |
dd8086 |
Mode 1 is the data storage mode used by to store computer data. There
|
|
Packit |
dd8086 |
are 3 layers of error correction. A Compact Disc using only this format can
|
|
Packit |
dd8086 |
hold at most 650 MB. The data is laid out in basically the same way as
|
|
Packit |
dd8086 |
in and audio CD format, except that the 2,352 bytes of data in each
|
|
Packit |
dd8086 |
block are broken down further. 2,048 of these bytes are for ``real''
|
|
Packit |
dd8086 |
data. The other 304 bytes are used for an additional level of error
|
|
Packit |
dd8086 |
detecting and correcting code. This is necessary because data CDs
|
|
Packit |
dd8086 |
cannot tolerate the loss of a handful of bits now and then, the way
|
|
Packit |
dd8086 |
audio CDs can.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In @value{libcdio} when you you want to read a mode1
|
|
Packit |
dd8086 |
sector you call the @code{cdio_read_mode1_sector()} or
|
|
Packit |
dd8086 |
@code{cdio_read_mode1_sectors()}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Mode 2
|
|
Packit |
dd8086 |
@subsection Mode 2 (2336 data bytes per sector)
|
|
Packit |
dd8086 |
@cindex Mode 2
|
|
Packit |
dd8086 |
Mode 2 data CDs are the same as mode 1 CDs except that the error
|
|
Packit |
dd8086 |
detecting and correcting codes are omitted. So still there are 2
|
|
Packit |
dd8086 |
layers of error correction. A Compact Disc using only this mode can
|
|
Packit |
dd8086 |
thus hold at most 742 MB. Similar to audio CDs, the mode 2 format
|
|
Packit |
dd8086 |
provides a more flexible vehicle for storing types of data that do not
|
|
Packit |
dd8086 |
require high data integrity: for example, graphics and video can use
|
|
Packit |
dd8086 |
this format. But in contrast to the Red Book standard, different modes
|
|
Packit |
dd8086 |
can be mixed together; this is the basis for the extensions to the
|
|
Packit |
dd8086 |
original data CD standards known as CD-ROM Extended Architecture, or
|
|
Packit |
dd8086 |
CD-ROM XA. CD-ROM XA formats currently in use are CD-I Bridge
|
|
Packit |
dd8086 |
formats, Photo CD and Video CD plus Sony's Playstation.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In @value{libcdio} when you you want to read a mode1
|
|
Packit |
dd8086 |
sector you call the @code{cdio_read_mode2_sector()} or
|
|
Packit |
dd8086 |
@code{cdio_read_mode2_sectors()}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Green Book
|
|
Packit |
dd8086 |
@section Green Book (CD-i)
|
|
Packit |
dd8086 |
@cindex Green Book
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This was a CD-ROM format developed by Philips for CD-i (an obsolete
|
|
Packit |
dd8086 |
embedded CD-ROM application allowing limited user user interaction
|
|
Packit |
dd8086 |
with films, games and educational applications). The format is ISO
|
|
Packit |
dd8086 |
9660 compliant and introduced mode 2 form 2 addressing. It also
|
|
Packit |
dd8086 |
contains XA (Extended Architecture) attributes.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Although some Green Book discs contain CD-i applications which can
|
|
Packit |
dd8086 |
only be played on a CD-i player, others have films or music
|
|
Packit |
dd8086 |
videos. Video CDs in Green-Book format are labeled "Digital Video on
|
|
Packit |
dd8086 |
CD." The Green Book for video is largely superseded by White book
|
|
Packit |
dd8086 |
CD-ROM which draws on this specification.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node White Book
|
|
Packit |
dd8086 |
@section White Book (DV, Video CD)
|
|
Packit |
dd8086 |
@cindex Green Book
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The White Book was released by Sony, Philips, Matsushita, and JVC in
|
|
Packit |
dd8086 |
1993, defines the Video CD specification. The White Book is also known
|
|
Packit |
dd8086 |
as Digital Video (DV).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A Video CD contains one data track recorded in CD-ROM XA Mode 2 Form
|
|
Packit |
dd8086 |
2. It is always the first track on the disc (Track 1). The ISO-9660
|
|
Packit |
dd8086 |
file structure and a CD-i application program are recorded in this
|
|
Packit |
dd8086 |
track, as well as the Video CD Information Area which gives general
|
|
Packit |
dd8086 |
information about the Video Compact Disc. After the data track, video
|
|
Packit |
dd8086 |
is written in one or more subsequent tracks within the same
|
|
Packit |
dd8086 |
session. These tracks are also recorded in Mode 2 Form 2.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In @value{libcdio} when you you want to read a mode2 format 2 audio
|
|
Packit |
dd8086 |
sector you call the @code{cdio_read_mode2_sector()} or
|
|
Packit |
dd8086 |
@code{cdio_read_mode2_sectors()} setting @code{b_form2} to @code{true}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CD Image Formats
|
|
Packit |
dd8086 |
@chapter CD Image Formats
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* CDRDAO TOC Format::
|
|
Packit |
dd8086 |
* CDRWIN BIN/CUE Format::
|
|
Packit |
dd8086 |
* NRG Format::
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In both the @command{cdrdao} and bin/cue formats there is one meta-file with
|
|
Packit |
dd8086 |
extensions @code{.toc} or @code{.cue} respectively and one or more
|
|
Packit |
dd8086 |
files (often with the extension @code{.bin}) which contains the
|
|
Packit |
dd8086 |
content of tracks. The format of the track data is often
|
|
Packit |
dd8086 |
interchangeable between the two formats. For example, in
|
|
Packit |
dd8086 |
@value{libcdio}'s regression tests we make use of this to reduce the
|
|
Packit |
dd8086 |
size of the test data and just provide alternate meta-data files
|
|
Packit |
dd8086 |
(@code{.toc} or @code{.cue}).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In contrast to the first two formats, the NRG format consists of a
|
|
Packit |
dd8086 |
single file. This has the advantage of being a self-contained
|
|
Packit |
dd8086 |
unit: in the other two formats it is possible for the meta file to
|
|
Packit |
dd8086 |
refer to a file that can't be found. A disadvantage of the NRG format
|
|
Packit |
dd8086 |
is that the meta data can't be easily viewed or modified say in a text
|
|
Packit |
dd8086 |
file as it can be with the first two formats. In conjunction with this
|
|
Packit |
dd8086 |
disadvantage is another disadvantage that the format is not
|
|
Packit |
dd8086 |
documented, so how @value{libcdio} interprets an NRG image is based on
|
|
Packit |
dd8086 |
inference. It is recommended that one of the other forms be used
|
|
Packit |
dd8086 |
instead of NRG where possible.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CDRDAO TOC Format
|
|
Packit |
dd8086 |
@section CDRDAO TOC Format
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This is @command{cdrdao}'s CD-image description format. Since this
|
|
Packit |
dd8086 |
program is GPL and everything about it is in the open, it is the
|
|
Packit |
dd8086 |
preferred format to use. (Alas, at present it isn't as well supported
|
|
Packit |
dd8086 |
in @value{libcdio} as the BIN/CUE format.)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The @emph{toc}-file describes what data is written to the media in the
|
|
Packit |
dd8086 |
@acronym{CD-ROM}; it allows control over track/index positions,
|
|
Packit |
dd8086 |
pre-gaps and sub-channel information. It is a text file, so a text
|
|
Packit |
dd8086 |
editor can be used to create, view or modify it.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The @cite{cdrdao(1) manual page}, contains more information about this
|
|
Packit |
dd8086 |
format.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@subsection CDRDAO Grammar
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Below are the lexical tokens and grammar for a cdrdao TOC. It was
|
|
Packit |
dd8086 |
taken from the cdrdao's pacct grammar; the token and nonterminal names
|
|
Packit |
dd8086 |
are the same.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@example
|
|
Packit |
dd8086 |
#lexclass START
|
|
Packit |
dd8086 |
#token Eof "@@"
|
|
Packit |
dd8086 |
#token "[\t\r\ ]+"
|
|
Packit |
dd8086 |
#token Comment "//~[\n@@]*"
|
|
Packit |
dd8086 |
#token "\n"
|
|
Packit |
dd8086 |
#token BeginString "\""
|
|
Packit |
dd8086 |
#token Integer "[0-9]+"
|
|
Packit |
dd8086 |
#tokclass AudioFile @{ "AUDIOFILE" "FILE" @}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#lexclass STRING
|
|
Packit |
dd8086 |
#token EndString "\""
|
|
Packit |
dd8086 |
#token StringQuote "\\\""
|
|
Packit |
dd8086 |
#token StringOctal "\\[0-9][0-9][0-9]"
|
|
Packit |
dd8086 |
#token String "\\"
|
|
Packit |
dd8086 |
#token String "[ ]+"
|
|
Packit |
dd8086 |
#token String "~[\\\n\"\t ]*"
|
|
Packit |
dd8086 |
@end example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<toc> ::= ( "CATALOG" <string> | <tocType> )* @{ <cdTextGlobal> @}
|
|
Packit |
dd8086 |
( <track> )+ Eof
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<track> ::= "TRACK" <trackMode>
|
|
Packit |
dd8086 |
@{ <subChannelMode> @}
|
|
Packit |
dd8086 |
( "ISRC" <string> | @{ "NO" @} "COPY" | @{ "NO" @} "PRE_EMPHASIS"
|
|
Packit |
dd8086 |
| "TWO_CHANNEL_AUDIO" | "FOUR_CHANNEL_AUDIO" )*
|
|
Packit |
dd8086 |
@{ <cdTextTrack> @}
|
|
Packit |
dd8086 |
@{ "PREGAP" <msf> @}
|
|
Packit |
dd8086 |
( <subTrack> | "START" @{ msf @} | "END" @{ msf @} )+
|
|
Packit |
dd8086 |
( "INDEX" <msf> )*
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<subTrack> ::=
|
|
Packit |
dd8086 |
AudioFile <string> @{ "SWAP" @} @{ "#" <sLong> @} <samples>
|
|
Packit |
dd8086 |
| "DATAFILE" <string> @{ "#" <sLong> @{ <dataLength> @} @}
|
|
Packit |
dd8086 |
| "FIFO" <string> <dataLength>
|
|
Packit |
dd8086 |
| "SILENCE" <samples>
|
|
Packit |
dd8086 |
| "ZERO" @{ dataMode @} @{ <subChannelMode> @} <dataLength>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<string> ::= BeginString ( String | StringQuote | StringOctal )+
|
|
Packit |
dd8086 |
EndString
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<stringEmpty> ::= BeginString ( String | StringQuote | StringOctal )*
|
|
Packit |
dd8086 |
EndString
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<uLong> ::= Integer
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<sLong> ::= Integer
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<msf> ::= Integer ":" Integer ":" Integer
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<samples> ::= <msf> | <uLong>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<dataLength> ::= <msf> | <uLong>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<dataMode> ::= "AUDIO" | "MODE0" | "MODE1" | "MODE1_RAW" | "MODE2"
|
|
Packit |
dd8086 |
| "MODE2_RAW" | "MODE2_FORM1" | "MODE2_FORM2" | "MODE2_FORM_MIX"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<trackMode> ::= "AUDIO" | "MODE1" | "MODE1_RAW" | "MODE2"
|
|
Packit |
dd8086 |
| "MODE2_RAW" | "MODE2_FORM1" | "MODE2_FORM2" | "MODE2_FORM_MIX"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<subChannelMode> ::= "RW" | "RW_RAW"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<tocType> ::= "CD_DA" | "CD_ROM" | "CD_ROM_XA" | "CD_I"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<packType> ::= "TITLE" | "PERFORMER" | "SONGWRITER" | "COMPOSER" | "ARRANGER"
|
|
Packit |
dd8086 |
| "MESSAGE" | "DISC_ID" | "GENRE" | "TOC_INFO1" | "TOC_INFO2"
|
|
Packit |
dd8086 |
| "RESERVED1" | "RESERVED2" | "RESERVED3" | "RESERVED4" | "UPC_EAN" |
|
|
Packit |
dd8086 |
"ISRC" | "SIZE_INFO"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<binaryData> ::= "@{"
|
|
Packit |
dd8086 |
@{ Integer ( "," Integer )* @}
|
|
Packit |
dd8086 |
"@}"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<cdTextItem> ::= <packType> ( <stringEmpty> | <binaryData> )
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<cdTextBlock> ::= "LANGUAGE" Integer "@{" ( <cdTextItem> )* "@}"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<cdTextLanguageMap> ::=
|
|
Packit |
dd8086 |
"LANGUAGE_MAP" "@{"
|
|
Packit |
dd8086 |
( Integer ":" ( Integer | "EN" ) )+
|
|
Packit |
dd8086 |
"@}"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<cdTextTrack> ::= "CD_TEXT" "@{" ( <cdTextBlock> )* "@}"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<cdTextGlobal> ::= "CD_TEXT" "@{" @{ <cdTextLanguageMap> @} ( <cdTextBlock> )* "@}"
|
|
Packit |
dd8086 |
@end example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CDRWIN BIN/CUE Format
|
|
Packit |
dd8086 |
@section CDRWIN BIN/CUE Format
|
|
Packit |
dd8086 |
@cindex BIN/CUE, CD Image Format
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The format referred to as @emph{CDRWIN BIN/CUE Format} in this manual
|
|
Packit |
dd8086 |
is a popular CD image format used in the @acronym{PC} world. Not
|
|
Packit |
dd8086 |
unlike @command{cdrdao}'s TOC file, the @emph{cue} file describes the
|
|
Packit |
dd8086 |
track layout, i.e. how the sectors are to be placed on the CD
|
|
Packit |
dd8086 |
media. The @emph{cue} file usually contains a reference to a file
|
|
Packit |
dd8086 |
traditionally having the @file{.bin} extension in its filename, the
|
|
Packit |
dd8086 |
@emph{bin} file. This @emph{bin} file contains the sector data payload
|
|
Packit |
dd8086 |
which is to be written to the CD medium according to the description
|
|
Packit |
dd8086 |
in the @emph{cue} file.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The following is an attempt to describe the subset of the @file{.cue}
|
|
Packit |
dd8086 |
file syntax used in @value{libcdio} and vcdimager in an EBNF-like
|
|
Packit |
dd8086 |
notation:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@subsection BIN/CUE Grammar
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@example
|
|
Packit |
dd8086 |
@cartouche
|
|
Packit |
dd8086 |
<cue-document> ::= +( <file-line> +<track-expr> )
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<digit> ::= "0" | "1" ... "8" | "9"
|
|
Packit |
dd8086 |
<number> ::= +<digit>
|
|
Packit |
dd8086 |
<msf> ::= <digit><digit> ":" <digit><digit> ":" <digit><digit>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<file-line> ::= "FILE" <pathname-expr> <file-type> <EOL>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<pathname-expr> ::= [ "\"" ] <pathname-str-without-spaces> [ "\"" ]
|
|
Packit |
dd8086 |
| "\"" <pathname-str> "\""
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<file-type> ::= "BINARY"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<track-expr> ::= <track-line> [ <flag-line> ]
|
|
Packit |
dd8086 |
[ <pregap-line> ] *<index-line> [ <postgap-line> ]
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<flag-line> ::= "FLAGS" *<flag-type> <EOL>
|
|
Packit |
dd8086 |
<flag-type> ::= "DCP"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<track-line> ::= "TRACK" <number> <track-type> <EOL>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<pregap-line> ::= "PREGAP" <msf> <EOL>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<index-line> ::= "INDEX" <number> <msf> <EOL>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<postgap-line> ::= "POSTGAP" <msf> <EOL>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<track-type> ::= "AUDIO" | "MODE1/2048" | "MODE1/2352"
|
|
Packit |
dd8086 |
| "MODE2/2336" | "MODE2/2352"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
<comment-line> ::= "REM" *<char> <EOL>
|
|
Packit |
dd8086 |
@end cartouche
|
|
Packit |
dd8086 |
@end example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node NRG Format
|
|
Packit |
dd8086 |
@section NRG Format
|
|
Packit |
dd8086 |
@cindex Nero NRG, CD-Image format
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The format referred to as @emph{NRG Format} in this manual is another
|
|
Packit |
dd8086 |
popular CD image format. It is available only on Nero software
|
|
Packit |
dd8086 |
on a Microsoft Windows Operating System. It is proprietary and not
|
|
Packit |
dd8086 |
generally published, so the information we have comes from guessing
|
|
Packit |
dd8086 |
based on sample CD images. So support for this is incomplete and using
|
|
Packit |
dd8086 |
this format is not recommended.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Unlike @command{cdrdao}'s TOC file the BIN/CUE format everything is
|
|
Packit |
dd8086 |
contained in one file that one can edit. Meta information such as the
|
|
Packit |
dd8086 |
number of tracks and track format is contained at the end of the
|
|
Packit |
dd8086 |
file. This information is not intended to be edited through a text
|
|
Packit |
dd8086 |
editor.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CD Units
|
|
Packit |
dd8086 |
@chapter The units that make up a CD
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* Tracks:: Tracks
|
|
Packit |
dd8086 |
* Sectors:: Block addressing (MSF, LSN, LBA)
|
|
Packit |
dd8086 |
* Pre-gaps:: Track pre-gaps
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Tracks
|
|
Packit |
dd8086 |
@section tracks --- disc subdivisions
|
|
Packit |
dd8086 |
@cindex track
|
|
Packit |
dd8086 |
@cindex gaps
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In this section we describe CD properties and terms that we make use
|
|
Packit |
dd8086 |
of in @value{libcdio}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A CD is formatted into a number of @term{tracks}, and a CD can hold at
|
|
Packit |
dd8086 |
most 99 such tracks. This is defined by @code{CDIO_CD_MAX_TRACKS} in
|
|
Packit |
dd8086 |
@file{cdio/sector.h}. Between some tracks CD specifications require a
|
|
Packit |
dd8086 |
``2 second'' in gap (called a @term{lead-in gap}. This is unused space
|
|
Packit |
dd8086 |
with no ``data'' similar to the space between tracks on an old
|
|
Packit |
dd8086 |
phonograph. The word ``second'' here really refers to a measure of
|
|
Packit |
dd8086 |
space and not really necessarily an amount of time. However in the
|
|
Packit |
dd8086 |
special case that the CD encodes an audio CD or CD-DA, the amount of
|
|
Packit |
dd8086 |
time to play a gap of this size will take 2 seconds.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@cindex lead out
|
|
Packit |
dd8086 |
The beginning (or inner edge) of the CD is supposed to have a ``2
|
|
Packit |
dd8086 |
second'' lead-in gap and there is supposed to be another ``2 second''
|
|
Packit |
dd8086 |
@term{lead-out} gap at the end (or outer edge) of the CD.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
People have discovered that they can put useful data in the @term{lead-in}
|
|
Packit |
dd8086 |
and @term{lead-out} gaps, and their equipment can read this, violating
|
|
Packit |
dd8086 |
the standards but allowing a CD to store more data.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In order to determine the number of tracks on a CD and where they
|
|
Packit |
dd8086 |
start, commands are used to get this table-of-contents or @term{TOC}
|
|
Packit |
dd8086 |
information. Asking about the start of the @term{lead-out track}
|
|
Packit |
dd8086 |
gives the amount of data stored on the Compact Disk. To make it easy
|
|
Packit |
dd8086 |
to specify this leadout track, special constant 0xAA (decimal 170) is
|
|
Packit |
dd8086 |
used to indicate it. This is safe since this is higher than the
|
|
Packit |
dd8086 |
largest legal track position. In @value{libcdio},
|
|
Packit |
dd8086 |
@code{CDIO_CDROM_LEADOUT_TRACK} is defined to be this special value.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Sectors
|
|
Packit |
dd8086 |
@section block addressing (MSF, LSN, LBA)
|
|
Packit |
dd8086 |
@cindex MSF
|
|
Packit |
dd8086 |
@cindex LSN
|
|
Packit |
dd8086 |
@cindex LBA
|
|
Packit |
dd8086 |
@cindex sectors
|
|
Packit |
dd8086 |
@cindex frames
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A track is broken up into a number of 2352-byte @emph{blocks} which we
|
|
Packit |
dd8086 |
sometimes call @emph{sectors} or @emph{frames}. Whereas tracks may
|
|
Packit |
dd8086 |
have a gap between them, a block or sector does not. (In
|
|
Packit |
dd8086 |
@value{libcdio} the block size constant is defined using
|
|
Packit |
dd8086 |
@code{CDIO_CD_FRAMESIZE_RAW}).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A Compact Disc has a limit on the number of blocks or sectors. This
|
|
Packit |
dd8086 |
values is defined by constant @code{CDIO_CD_MAX_LSN} in
|
|
Packit |
dd8086 |
@file{cdio/sector.h}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
One can addressing a block in one of three formats. The oldest format
|
|
Packit |
dd8086 |
is by it's minute/second/frame number, also referred to as @term{MSF}
|
|
Packit |
dd8086 |
and written in time-like format MM:SS:FF (e.g. 30:01:40). It is best
|
|
Packit |
dd8086 |
suited in audio (Red Book) applications. In @value{libcdio}, the type
|
|
Packit |
dd8086 |
@code{msf_t} can be used to declare variables to hold such
|
|
Packit |
dd8086 |
values. Minute, second and frame values are one byte @emph{and stored
|
|
Packit |
dd8086 |
BCD notation}.@footnote{Perhaps this is a @value{libcdio} design
|
|
Packit |
dd8086 |
flaw. It was originally done I guess because it was convenient for
|
|
Packit |
dd8086 |
VCDs.} There are @value{libcdio} conversion routines
|
|
Packit |
dd8086 |
@code{cdio_from_bcd8()} and @code{cdio_to_bcd8()} to convert the
|
|
Packit |
dd8086 |
minute, second, and frame values into or out of integers. If you want
|
|
Packit |
dd8086 |
to print a field in a BCD-encoded MSF, one can use the format
|
|
Packit |
dd8086 |
specifier @code{%x} @emph{(not @code{%d})} and things will come out
|
|
Packit |
dd8086 |
right.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In the MSF notation, there are 75 ``frames'' in a ``second,'' and the
|
|
Packit |
dd8086 |
familiar (if awkward) 60 seconds in a minute. @emph{Frame} here is
|
|
Packit |
dd8086 |
what we called a @emph{block} above. The CD specification defines
|
|
Packit |
dd8086 |
``frame'' to be @emph{another} unit which makes up a block. Very
|
|
Packit |
dd8086 |
confusing. A frame is also sometimes called a sector, analogous to
|
|
Packit |
dd8086 |
hard-disk terminology.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Even more confusing is using this time-like notation for an address or
|
|
Packit |
dd8086 |
for a length. Too often people confuse the MSF notation this with an
|
|
Packit |
dd8086 |
amount of time. A ``second'' (or @code{CDIO_CD_FRAMES_PER_SEC} blocks)
|
|
Packit |
dd8086 |
in this notation is only a second of playing time for something
|
|
Packit |
dd8086 |
encoded as CD-DA. It does @emph{not} necessarily represent the amount
|
|
Packit |
dd8086 |
time that it will take to play a of Video CD---usually you need more
|
|
Packit |
dd8086 |
blocks than this. Nor does it represent the amount of data used to
|
|
Packit |
dd8086 |
play a second of an MP3---usually you need fewer blocks than this. It
|
|
Packit |
dd8086 |
is also not the amount of time your CD-ROM will take to read a
|
|
Packit |
dd8086 |
``second'' of data off a Compact Disc: for example a 12x CD player
|
|
Packit |
dd8086 |
will read 12x @code{CDIO_CD_FRAMES_PER_SEC}
|
|
Packit |
dd8086 |
@code{CDIO_CD_FRAMSIZE_RAW}-byte blocks in a one second of time.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
When programming, unless one is working with a CD-DA (and even here,
|
|
Packit |
dd8086 |
only in a time-like fashion), is generally more cumbersome to use an
|
|
Packit |
dd8086 |
MSF rather than a LBA or LSN described below, since subtraction of two
|
|
Packit |
dd8086 |
MSF's has the awkwardness akin to subtraction using Roman Numerals.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A simpler way to address a block is to use a ``Logical Sector Number''
|
|
Packit |
dd8086 |
(@term{LSN}) or a ``Logical Block Address (@term{LBA}). In the MMC-5
|
|
Packit |
dd8086 |
glossary these are synonymous terms. However historically it has been
|
|
Packit |
dd8086 |
used differently. In libcdio, to convert a LBA into an LSN you just
|
|
Packit |
dd8086 |
subtract 150. Both LBA's and LSN's can be negative.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Pre-gaps
|
|
Packit |
dd8086 |
@section track pre-gaps -- @acronym{CD-DA} discs and gaps
|
|
Packit |
dd8086 |
@cindex CD-DA
|
|
Packit |
dd8086 |
@cindex gaps
|
|
Packit |
dd8086 |
@cindex lead in
|
|
Packit |
dd8086 |
@cindex lead out
|
|
Packit |
dd8086 |
@cindex pre-gap
|
|
Packit |
dd8086 |
@cindex Q sub-channel
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Gaps are possibly one of the least understood topics in audio discs.
|
|
Packit |
dd8086 |
In the case of @acronym{CD-DA} discs, standards require a silent 2
|
|
Packit |
dd8086 |
second gap before the first audio track and after the last audio track
|
|
Packit |
dd8086 |
(in each session.) These are respectively referred to as
|
|
Packit |
dd8086 |
@term{lead-in} and @term{lead-out} gaps. No other gaps are required.
|
|
Packit |
dd8086 |
It is important not to confuse the required @term{lead-in} and
|
|
Packit |
dd8086 |
@term{lead-out} gaps with the optional track @term{pre-gap}s. Track
|
|
Packit |
dd8086 |
@term{pre-gap}s are the gaps that may occur between audio tracks.
|
|
Packit |
dd8086 |
Typically, track @term{pre-gap}s are filled with silence so that the
|
|
Packit |
dd8086 |
listener knows that one song has ended, and the next will soon begin.
|
|
Packit |
dd8086 |
However, track @term{pre-gap}s do not have to contain silence. One
|
|
Packit |
dd8086 |
exception is an audio disc of a live performance. Because the
|
|
Packit |
dd8086 |
performer may seamlessly move from one piece of the performance to the
|
|
Packit |
dd8086 |
next, it would be unnatural for the disc to contain silence between
|
|
Packit |
dd8086 |
the two pieces. Instead, the track number updates with no
|
|
Packit |
dd8086 |
interruption in the performance. This allows the listener to either
|
|
Packit |
dd8086 |
hear the entire performance without unnatural interruptions, or to
|
|
Packit |
dd8086 |
conveniently skip to certain pieces of the performance. Finally, some
|
|
Packit |
dd8086 |
@acronym{CD-DA} discs--whose behavior will be described below--lack
|
|
Packit |
dd8086 |
track @term{pre-gap}s altogether although they must still include the
|
|
Packit |
dd8086 |
@term{lead-in} and @term{lead-out} gaps.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In order to understand the track @term{pre-gap}s that occur between
|
|
Packit |
dd8086 |
audio tracks, it is necessary to understand how CD players display the
|
|
Packit |
dd8086 |
track number and time. Embedded in each block of audio data is
|
|
Packit |
dd8086 |
non-audio information known as the @term{Q sub-channel}. The
|
|
Packit |
dd8086 |
@term{Q sub-channel} data tells the CD player what track number and time
|
|
Packit |
dd8086 |
it should display while it is playing the block of audio data in which
|
|
Packit |
dd8086 |
the @term{Q sub-channel} data is embedded. Near the end of some
|
|
Packit |
dd8086 |
tracks, the @term{Q sub-channel} may instruct the CD player to update
|
|
Packit |
dd8086 |
the track number to the next track, and display a count down to the
|
|
Packit |
dd8086 |
next track, often starting at -2 seconds and proceeding to zero. This
|
|
Packit |
dd8086 |
is known as an audio track @term{pre-gap}. It may either contain
|
|
Packit |
dd8086 |
silence, or as previously discussed--in the case of live
|
|
Packit |
dd8086 |
performances--it may contain audio. Almost as often as not, there is
|
|
Packit |
dd8086 |
no @term{pre-gap} whatsoever. Regardless, an audio track
|
|
Packit |
dd8086 |
@term{pre-gap} is purely determined by the contents of the
|
|
Packit |
dd8086 |
@term{Q sub-channel}, which is embedded in each audio sector. This has
|
|
Packit |
dd8086 |
some interesting implications for the track forward button.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
When the track forward button is pressed on a CD player, the CD player
|
|
Packit |
dd8086 |
advances to the next track, skipping that track's @term{pre-gap}.
|
|
Packit |
dd8086 |
This is because the CD player uses the starting address of the track
|
|
Packit |
dd8086 |
from the disc's table of contents (TOC) to determine where to start
|
|
Packit |
dd8086 |
playing a track when either the track forward or track backward
|
|
Packit |
dd8086 |
buttons are pressed. So to hear a @term{pre-gap} for track 4, the
|
|
Packit |
dd8086 |
listener must either listen to track 3 first, or use the track forward
|
|
Packit |
dd8086 |
or backward buttons to go to track 4, then use the seek backward
|
|
Packit |
dd8086 |
button to back up into track 4's @term{pre-gap}, which is really part
|
|
Packit |
dd8086 |
of track 3, at least according to the TOC. Track 1 @term{pre-gap}s
|
|
Packit |
dd8086 |
are especially interesting because some commercial discs have audio
|
|
Packit |
dd8086 |
hidden before the beginning of the first track! The only way to hear
|
|
Packit |
dd8086 |
this hidden audio with a standard player is to use the seek backward
|
|
Packit |
dd8086 |
button as soon as track 1 begins playing!
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Audio track @term{pre-gap}s may be specified in a couple of different
|
|
Packit |
dd8086 |
ways in the popular cue file format. The first way of specifying a
|
|
Packit |
dd8086 |
@term{pre-gap} is to use the @command{PREGAP} command. This will
|
|
Packit |
dd8086 |
place a @term{pre-gap} containing silence before a track. The second
|
|
Packit |
dd8086 |
way of specifying a @term{pre-gap} is to give a track an
|
|
Packit |
dd8086 |
@command{INDEX 00} as well as the more normal @command{INDEX 01}.
|
|
Packit |
dd8086 |
@command{INDEX 01} will be used to specify the start of the track in
|
|
Packit |
dd8086 |
the disc's TOC, while @command{INDEX 00} will be used to specify the
|
|
Packit |
dd8086 |
start of the track's @term{pre-gap} as recorded in the @term{Q sub-channel}.
|
|
Packit |
dd8086 |
@command{INDEX 00} is ordinarily used for specifying
|
|
Packit |
dd8086 |
track @term{pre-gap}s that contain audio rather than silence. Thus,
|
|
Packit |
dd8086 |
the cue file format may be used to specify track @term{pre-gap}s with
|
|
Packit |
dd8086 |
silence or audio, depending on whether the @command{PREGAP} or
|
|
Packit |
dd8086 |
@command{INDEX 00} commands are specified. If neither type of
|
|
Packit |
dd8086 |
@term{pre-gap} is specified for a track, no @term{pre-gap} is created
|
|
Packit |
dd8086 |
for that track, which merely means the absence of @term{pre-gap}
|
|
Packit |
dd8086 |
information in the @term{Q sub-channel}, and the lack of a short count
|
|
Packit |
dd8086 |
down to the next track.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Various @acronym{CD-DA} ripping programs take various approaches to
|
|
Packit |
dd8086 |
track @term{pre-gap}s. Some ripping programs ignore track
|
|
Packit |
dd8086 |
@term{pre-gap}s altogether, relying solely on the disc's TOC to
|
|
Packit |
dd8086 |
determine where tracks begin and end. If a disc is ripped with such a
|
|
Packit |
dd8086 |
program, then re-burned later, the resulting disc will lack track
|
|
Packit |
dd8086 |
@term{pre-gap}s, and thereby lack the playback behavior of counting
|
|
Packit |
dd8086 |
down to the next track. Other ripping programs detect track
|
|
Packit |
dd8086 |
@term{pre-gap}s and record them in the popular cue file format among
|
|
Packit |
dd8086 |
others. Such ripping programs sometimes allow the user to determine
|
|
Packit |
dd8086 |
whether track @term{pre-gap}s will be appended to the prior track or
|
|
Packit |
dd8086 |
pre-pended to the track to which they "belong". Note that if a
|
|
Packit |
dd8086 |
ripping program is ignorant of track @term{pre-gap}s, the track
|
|
Packit |
dd8086 |
@term{pre-gap}s will be appended to the prior track, because that is
|
|
Packit |
dd8086 |
where the disc's TOC puts them. Thus, there are many different ways
|
|
Packit |
dd8086 |
an application may chose to deal with track @term{pre-gap}s.
|
|
Packit |
dd8086 |
Consequently, @kbd{libcdio} does not dictate the policy a ripping
|
|
Packit |
dd8086 |
program should use in dealing with track @term{pre-gap}s. Hence,
|
|
Packit |
dd8086 |
@kbd{libcdio} provides the @code{cdio_get_track_pregap_[lba|lsn]()}
|
|
Packit |
dd8086 |
interfaces to allow the application to deal with track @term{pre-gap}s
|
|
Packit |
dd8086 |
as it sees fit.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Note that the @code{cdio_get_track_pregap_[lba|lsn]()} interfaces
|
|
Packit |
dd8086 |
currently only provide information for CDRDAO TOC, CDRWIN BIN/CUE, and
|
|
Packit |
dd8086 |
NRG images. Getting the track @term{pre-gap}s from a CD drive is a
|
|
Packit |
dd8086 |
more complicated problem because not all CD drives support reading the
|
|
Packit |
dd8086 |
@term{Q sub-channel} @emph{directly} at @emph{high} speed, and there is no
|
|
Packit |
dd8086 |
interface to determine whether or not a drive supports this optional
|
|
Packit |
dd8086 |
feature, aside from trying to read the @term{Q sub-channel}, and
|
|
Packit |
dd8086 |
possibly incurring IO errors. However, all drives @emph{do} support reading
|
|
Packit |
dd8086 |
the @term{Q sub-channel} @emph{indirectly} while playing an audio disc by
|
|
Packit |
dd8086 |
asking the drive for the current position. Unfortunately, this occurs
|
|
Packit |
dd8086 |
at normal playback speed, and requires a certain settling time after
|
|
Packit |
dd8086 |
the disc starts playing. Thus, using this @emph{slow} interface
|
|
Packit |
dd8086 |
requires a more sophisticated algorithm, such as binary search or some
|
|
Packit |
dd8086 |
heuristic, like backing up progressively from the end of the prior
|
|
Packit |
dd8086 |
track to look for the next track's @term{pre-gap}. Note that CD
|
|
Packit |
dd8086 |
drives seek @emph{slow}ly, so it is better to simply use a drive that
|
|
Packit |
dd8086 |
can read the @term{Q sub-channel} directly at @emph{high} speed, and
|
|
Packit |
dd8086 |
avoid complicated software solutions. (Not to mention that if the
|
|
Packit |
dd8086 |
user has an older system with an analog audio cable hooked up between
|
|
Packit |
dd8086 |
their soundboard and their drive, and a ripping program uses the
|
|
Packit |
dd8086 |
@emph{slow} interface, the user will hear bits of the audio on the
|
|
Packit |
dd8086 |
disc!) Consequently, because there is no good universal solution to
|
|
Packit |
dd8086 |
the problem of reading the @term{Q sub-channel} from a drive,
|
|
Packit |
dd8086 |
@kbd{libcdio} currently leaves this problem up to the application, a
|
|
Packit |
dd8086 |
problem which is readily approachable through either @kbd{libcdio}'s
|
|
Packit |
dd8086 |
MMC interface or @kbd{libcdio}'s cdda interface. For an example of
|
|
Packit |
dd8086 |
one such application, see @url{https://gna.org/projects/cued/}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The preceding section on track @term{pre-gaps} and @acronym{CD-DA} was
|
|
Packit |
dd8086 |
contributed by Robert William Fuller (@email{hydrologiccycle@@gmail.com}).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node How to use
|
|
Packit |
dd8086 |
@chapter How to use
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The @value{libcdio} package comes with a number of small example
|
|
Packit |
dd8086 |
programs in the directory @file{example} which demonstrate different
|
|
Packit |
dd8086 |
aspects of the library and show how to use the library. The source
|
|
Packit |
dd8086 |
code to all of the examples here are contained on the package.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Other sources for examples would be the larger utility programs
|
|
Packit |
dd8086 |
@command{cd-drive}, @command{cd-info}, @command{cd-read},
|
|
Packit |
dd8086 |
@command{iso-info}, and @command{iso-read} which are all in the
|
|
Packit |
dd8086 |
@file{src} directory of the @value{libcdio} package. See also
|
|
Packit |
dd8086 |
@xref{Utility Programs}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* Include problem:: A note about including <cdio/cdio.h>
|
|
Packit |
dd8086 |
* Example 1:: list out tracks and LSNs
|
|
Packit |
dd8086 |
* Example 2:: list drivers available and default CD device
|
|
Packit |
dd8086 |
* Example 3:: figure out what kind of CD (image) we've got
|
|
Packit |
dd8086 |
* Example 4:: use libiso9660 to extract a file from an ISO-9660 image
|
|
Packit |
dd8086 |
* Example 5:: list CD-Text and CD disc mode info
|
|
Packit |
dd8086 |
* Example 6:: run a MMC INQUIRY command
|
|
Packit |
dd8086 |
* Example 7:: using the CD Paranoia library for CD-DA reading
|
|
Packit |
dd8086 |
* Example 8:: Setting output verbosity
|
|
Packit |
dd8086 |
* All sample programs:: list of all programs in the example directory
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Include problem
|
|
Packit |
dd8086 |
@section A note about including @code{<cdio/cdio.h>}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
libcdio installs @code{<cdio/cdio_config.h>}. This file contains all of
|
|
Packit |
dd8086 |
the C Preprocessor values from @code{config.h} (created by configure).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This header can be used to consult exactly how libcdio was built. Initially
|
|
Packit |
dd8086 |
I had selected ``interesting'' values, but this became too hard to maintain.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
One set of values that libdio needs internally is the whether the CPU
|
|
Packit |
dd8086 |
that was used to compile libcdio is BigEndian or not; it can get this
|
|
Packit |
dd8086 |
from libcdio's @code{config.h} which is not installed and preferred or
|
|
Packit |
dd8086 |
@code{cdio/cdio_config.h}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Some of the libcdio programs like the demo programs include
|
|
Packit |
dd8086 |
@code{config.h} for the generic reasons that the configuration-created
|
|
Packit |
dd8086 |
@code{config.h} file is used: to figure out what headers are available.
|
|
Packit |
dd8086 |
For example, do we have @code{<unistd.h>}?
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The file @code{config.h} is generated by an autotools-generated
|
|
Packit |
dd8086 |
@code{configure} script. It doesn't check to see if it has been included
|
|
Packit |
dd8086 |
previously.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Later, the demo programs include @code{<cdio.h>} to get libcdio headers.
|
|
Packit |
dd8086 |
But because libcdio needs some of the same information like the BigEndian
|
|
Packit |
dd8086 |
value, this creates a duplicate include.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The way I get around this in the demo programs is by defining @code{__CDIO_CONFIG_H__} after
|
|
Packit |
dd8086 |
including @code{config.h} as follows:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
# define __CDIO_CONFIG_H__ 1
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Applications using libcdio may find it handy to do something like this as well.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Defining @code{__CDIO_CONFIG_H__} will make sure @code{config_cdio.h}
|
|
Packit |
dd8086 |
which is internally used, doesn't try to redefine preprocessor symbols.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Ok. But now what about the problem that there are common preprocessor
|
|
Packit |
dd8086 |
symbols in @code{config_cdio.h} that an application may want to define in a
|
|
Packit |
dd8086 |
different manner, like @code{PACKAGE_NAME}?
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For this, there is yet another header, @code{<cdio/cdio_unconfig.h>}.
|
|
Packit |
dd8086 |
This file undefines any symbol that @code{config.h} defines. And now we
|
|
Packit |
dd8086 |
bounce to the problem that there may be symbols that are normally
|
|
Packit |
dd8086 |
defined (@code{HAVE_UNISTD_H}) and you want to keep that way, but others that
|
|
Packit |
dd8086 |
you don't. So here is what I suggest:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
// for cdio:
|
|
Packit |
dd8086 |
#include <cdio.h>
|
|
Packit |
dd8086 |
#include <cdio_unconfig.h> # remove *all* symbols libcdio defines
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
// Add back in the ones you want your program
|
|
Packit |
dd8086 |
#include <config.h>
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The solution isn't the most simple or natural, but programming sometimes can
|
|
Packit |
dd8086 |
be difficult. If someone has a better solution, let me know.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Between header files @code{cdio_config.h} and @code{cdio_unconfig.h} and
|
|
Packit |
dd8086 |
all the fact that almost all headers@footnote{@code{<cdio_unconfig.h>} is
|
|
Packit |
dd8086 |
one of the few headers that doesn't set a preprocessor symbol: it does
|
|
Packit |
dd8086 |
its thing every time it is @code{#included}} define a symbol to indicate they
|
|
Packit |
dd8086 |
have been included, I think there is enough mechanism to cover most
|
|
Packit |
dd8086 |
situations that may arise.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 1
|
|
Packit |
dd8086 |
@section Example 1: list out tracks and LSNs
|
|
Packit |
dd8086 |
Here we will give an annotated example which can be found in the
|
|
Packit |
dd8086 |
distribution as @file{example/tracks.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
1: #include <stdio.h>
|
|
Packit |
dd8086 |
2: #include <sys/types.h>
|
|
Packit |
dd8086 |
3: #include <cdio/cdio.h>
|
|
Packit |
dd8086 |
4: int
|
|
Packit |
dd8086 |
5: main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
6: @{
|
|
Packit |
dd8086 |
7: CdIo_t *p_cdio = cdio_open ("/dev/cdrom", DRIVER_DEVICE);
|
|
Packit |
dd8086 |
8: track_t first_track_num = cdio_get_first_track_num(p_cdio);
|
|
Packit |
dd8086 |
9: track_t i_tracks = cdio_get_num_tracks(p_cdio);
|
|
Packit |
dd8086 |
10: int j, i=first_track_num;
|
|
Packit |
dd8086 |
11:
|
|
Packit |
dd8086 |
12: printf("CD-ROM Track List (%i - %i)\n", first_track_num, i_tracks);
|
|
Packit |
dd8086 |
13
|
|
Packit |
dd8086 |
14: printf(" #: LSN\n");
|
|
Packit |
dd8086 |
15:
|
|
Packit |
dd8086 |
16: for (j = 0; j < i_tracks; i++, j++) @{
|
|
Packit |
dd8086 |
17: lsn_t lsn = cdio_get_track_lsn(p_cdio, i);
|
|
Packit |
dd8086 |
18: if (CDIO_INVALID_LSN != lsn)
|
|
Packit |
dd8086 |
19: printf("%3d: %06d\n", (int) i, lsn);
|
|
Packit |
dd8086 |
20: @}
|
|
Packit |
dd8086 |
21: printf("%3X: %06d leadout\n", CDIO_CDROM_LEADOUT_TRACK,
|
|
Packit |
dd8086 |
22: cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK));
|
|
Packit |
dd8086 |
23: cdio_destroy(p_cdio);
|
|
Packit |
dd8086 |
24: return 0;
|
|
Packit |
dd8086 |
25: @}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Already from the beginning on line 2 we see something odd. The
|
|
Packit |
dd8086 |
@code{#include <sys/types.h>} is needed because @value{libcdio}
|
|
Packit |
dd8086 |
assumes type definitions exist for @code{uint32_t}, @code{uint16_t}
|
|
Packit |
dd8086 |
and so on. Alternatively you change line 2 to:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#define HAVE_SYS_TYPES_H
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
and @code{<cdio/cdio.h>} will insert line 2. If you use GNU autoconf
|
|
Packit |
dd8086 |
to configure your program, add @code{sys/types.h} to
|
|
Packit |
dd8086 |
@code{AC_HAVE_HEADERS} and @emph{it} will arrange for
|
|
Packit |
dd8086 |
@code{HAVE_SYS_TYPES_H} to get defined. If you don't have
|
|
Packit |
dd8086 |
@code{<sys/types.h>} but have some other include that defines these
|
|
Packit |
dd8086 |
types, put that instead of line 2. Or you could roll your own
|
|
Packit |
dd8086 |
typedefs. (Note: In the future, this will probably get ``fixed'' by
|
|
Packit |
dd8086 |
requiring glib.h.)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Okay after getting over the hurdle of line 2, the next line pretty
|
|
Packit |
dd8086 |
straightforward: you need to include this to get cdio definitions. One
|
|
Packit |
dd8086 |
of the types that is defined via line 3 is @code{CdIo_t} and a pointer
|
|
Packit |
dd8086 |
that is used pretty much in all operations. Line 6 initializes the
|
|
Packit |
dd8086 |
variable @code{cdio} which we will be using in all of the subsequent
|
|
Packit |
dd8086 |
libcdio calls. It does this via a call to @code{cdio_open()}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The second parameter of @code{cdio_open} is DRIVER_UNKNOWN. For any
|
|
Packit |
dd8086 |
given installation a number of Compact Disc device drivers may be
|
|
Packit |
dd8086 |
available. In particular it's not uncommon to have several drivers
|
|
Packit |
dd8086 |
that can read CD disk-image formats as well as a driver that handles
|
|
Packit |
dd8086 |
some CD-ROM piece of hardware. Using DRIVER_UNKNOWN as that second
|
|
Packit |
dd8086 |
parameter we let the library select a driver amongst those that are
|
|
Packit |
dd8086 |
available; generally the first hardware driver that is available is
|
|
Packit |
dd8086 |
the one selected.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If there is no CD in any of the CD-ROM drives or one does not have
|
|
Packit |
dd8086 |
access to the CD-ROM, it is possible that @value{libcdio} will find a
|
|
Packit |
dd8086 |
CD image in the directory you run this program and will pick a
|
|
Packit |
dd8086 |
suitable CD-image driver. If this is not what you want, but always
|
|
Packit |
dd8086 |
want some sort of CD-ROM driver (or failure if none), then use
|
|
Packit |
dd8086 |
DRIVER_DEVICE instead of DRIVER_UNKNOWN.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Note that in contrast to what is typically done using ioctls to read a
|
|
Packit |
dd8086 |
CD, you don't issue any sort of CD-ROM read TOC command---that is all
|
|
Packit |
dd8086 |
done by the driver. Of course, the information that you get from
|
|
Packit |
dd8086 |
reading the TOC is often desired: many tracks are on the CD, or what
|
|
Packit |
dd8086 |
number the first one is called. This is done through calls on lines 8
|
|
Packit |
dd8086 |
and 9.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For each track, we call a cdio routine to get the logical sector
|
|
Packit |
dd8086 |
number, @code{cdio_get_track_lsn()} on line 17 and print the track
|
|
Packit |
dd8086 |
number and LSN value. Finally we print out the ``lead-out track''
|
|
Packit |
dd8086 |
information and we finally call @code{cdio_destroy()} in line 23 to
|
|
Packit |
dd8086 |
indicate we're done with the CD.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 2
|
|
Packit |
dd8086 |
@section Example 2: list drivers available and default CD device
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
One thing that's a bit hockey in Example 1 is hard-coding the name of
|
|
Packit |
dd8086 |
the device used: @code{/dev/cdrom}. Although often this is the name of
|
|
Packit |
dd8086 |
a CD-ROM device on GNU/Linux and possibly some other Unix derivatives,
|
|
Packit |
dd8086 |
there are many OSs for which use a different device name.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In the next example, we'll let the driver give us the name of the CD-ROM
|
|
Packit |
dd8086 |
device that is right for it.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
1: #include <stdio.h>
|
|
Packit |
dd8086 |
2: #include <sys/types.h>
|
|
Packit |
dd8086 |
3: #include <cdio/cdio.h>
|
|
Packit |
dd8086 |
4: int
|
|
Packit |
dd8086 |
5: main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
6: @{
|
|
Packit |
dd8086 |
7: CdIo_t *p_cdio = cdio_open (NULL, DRIVER_DEVICE);
|
|
Packit |
dd8086 |
8: const driver_id_t *driver_id_p;
|
|
Packit |
dd8086 |
9:
|
|
Packit |
dd8086 |
10: if (NULL != p_cdio) @{
|
|
Packit |
dd8086 |
11: printf("The driver selected is %s\n", cdio_get_driver_name(p_cdio));
|
|
Packit |
dd8086 |
12: printf("The default device for this driver is %s\n\n",
|
|
Packit |
dd8086 |
13: cdio_get_default_device(p_cdio));
|
|
Packit |
dd8086 |
14: cdio_destroy(p_cdio);
|
|
Packit |
dd8086 |
15: @} else @{
|
|
Packit |
dd8086 |
16: printf("Problem in trying to find a driver.\n\n");
|
|
Packit |
dd8086 |
17: @}
|
|
Packit |
dd8086 |
18:
|
|
Packit |
dd8086 |
19: for (driver_id_p=cdio_drivers; *driver_id_p!=DRIVER_UNKNOWN; driver_id_p++)
|
|
Packit |
dd8086 |
20: if (cdio_have_driver(*driver_id_p))
|
|
Packit |
dd8086 |
21: printf("We have: %s\n", cdio_driver_describe(*driver_id_p));
|
|
Packit |
dd8086 |
22: else
|
|
Packit |
dd8086 |
23: printf("We don't have: %s\n", cdio_driver_describe(*driver_id_p));
|
|
Packit |
dd8086 |
24: return 0;
|
|
Packit |
dd8086 |
25: @}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 3
|
|
Packit |
dd8086 |
@section Example 3: figure out what kind of CD (image) we've got
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In this example is a somewhat simplified program to show the use of
|
|
Packit |
dd8086 |
@command{cdio_guess_cd_type()} to figure out the kind of CD image
|
|
Packit |
dd8086 |
we've got. This can be found in the distribution as @file{example/sample3.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/cd_types.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_analysis(cdio_iso_analysis_t cdio_iso_analysis,
|
|
Packit |
dd8086 |
cdio_fs_anal_t fs, int first_data, unsigned int num_audio,
|
|
Packit |
dd8086 |
track_t i_tracks, track_t first_track_num, CdIo_t *cdio)
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
switch(CDIO_FSTYPE(fs)) @{
|
|
Packit |
dd8086 |
case CDIO_FS_AUDIO:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660:
|
|
Packit |
dd8086 |
printf("CD-ROM with ISO 9660 filesystem");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_JOLIET) @{
|
|
Packit |
dd8086 |
printf(" and joliet extension level %d", cdio_iso_analysis.joliet_level);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_ROCKRIDGE)
|
|
Packit |
dd8086 |
printf(" and rockridge extensions");
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660_INTERACTIVE:
|
|
Packit |
dd8086 |
printf("CD-ROM with CD-RTOS and ISO 9660 filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_HIGH_SIERRA:
|
|
Packit |
dd8086 |
printf("CD-ROM with High Sierra filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_INTERACTIVE:
|
|
Packit |
dd8086 |
printf("CD-Interactive%s\n", num_audio > 0 ? "/Ready" : "");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_HFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with Macintosh HFS\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_HFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with both Macintosh HFS and ISO 9660 filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_UFS:
|
|
Packit |
dd8086 |
printf("CD-ROM with Unix UFS\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_EXT2:
|
|
Packit |
dd8086 |
printf("CD-ROM with Linux second extended filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_3DO:
|
|
Packit |
dd8086 |
printf("CD-ROM with Panasonic 3DO filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CDIO_FS_UNKNOWN:
|
|
Packit |
dd8086 |
printf("CD-ROM with unknown filesystem\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
switch(CDIO_FSTYPE(fs)) @{
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_9660_INTERACTIVE:
|
|
Packit |
dd8086 |
case CDIO_FS_ISO_HFS:
|
|
Packit |
dd8086 |
printf("ISO 9660: %i blocks, label `%.32s'\n",
|
|
Packit |
dd8086 |
cdio_iso_analysis.isofs_size, cdio_iso_analysis.iso_label);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
if (first_data == 1 && num_audio > 0)
|
|
Packit |
dd8086 |
printf("mixed mode CD ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_XA)
|
|
Packit |
dd8086 |
printf("XA sectors ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_MULTISESSION)
|
|
Packit |
dd8086 |
printf("Multisession");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_HIDDEN_TRACK)
|
|
Packit |
dd8086 |
printf("Hidden Track ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_PHOTO_CD)
|
|
Packit |
dd8086 |
printf("%sPhoto CD ",
|
|
Packit |
dd8086 |
num_audio > 0 ? " Portfolio " : "");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_CDTV)
|
|
Packit |
dd8086 |
printf("Commodore CDTV ");
|
|
Packit |
dd8086 |
if (first_data > 1)
|
|
Packit |
dd8086 |
printf("CD-Plus/Extra ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_BOOTABLE)
|
|
Packit |
dd8086 |
printf("bootable CD ");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_VIDEOCD && num_audio == 0) @{
|
|
Packit |
dd8086 |
printf("Video CD ");
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_SVCD)
|
|
Packit |
dd8086 |
printf("Super Video CD (SVCD) or Chaoji Video CD (CVD)");
|
|
Packit |
dd8086 |
if (fs & CDIO_FS_ANAL_CVD)
|
|
Packit |
dd8086 |
printf("Chaoji Video CD (CVD)");
|
|
Packit |
dd8086 |
printf("\n");
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
CdIo_t *p_cdio = cdio_open (NULL, DRIVER_UNKNOWN);
|
|
Packit |
dd8086 |
cdio_fs_anal_t fs=0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
track_t i_tracks;
|
|
Packit |
dd8086 |
track_t first_track_num;
|
|
Packit |
dd8086 |
lsn_t start_track; /* first sector of track */
|
|
Packit |
dd8086 |
lsn_t data_start =0; /* start of data area */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int first_data = -1; /* # of first data track */
|
|
Packit |
dd8086 |
int first_audio = -1; /* # of first audio track */
|
|
Packit |
dd8086 |
unsigned int num_data = 0; /* # of data tracks */
|
|
Packit |
dd8086 |
unsigned int num_audio = 0; /* # of audio tracks */
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_cdio) @{
|
|
Packit |
dd8086 |
printf("Problem in trying to find a driver.\n\n");
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
first_track_num = cdio_get_first_track_num(p_cdio);
|
|
Packit |
dd8086 |
i_tracks = cdio_get_num_tracks(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Count the number of data and audio tracks. */
|
|
Packit |
dd8086 |
for (i = first_track_num; i <= i_tracks; i++) @{
|
|
Packit |
dd8086 |
if (TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i)) @{
|
|
Packit |
dd8086 |
num_audio++;
|
|
Packit |
dd8086 |
if (-1 == first_audio) first_audio = i;
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
num_data++;
|
|
Packit |
dd8086 |
if (-1 == first_data) first_data = i;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* try to find out what sort of CD we have */
|
|
Packit |
dd8086 |
if (0 == num_data) @{
|
|
Packit |
dd8086 |
printf("Audio CD\n");
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
/* we have data track(s) */
|
|
Packit |
dd8086 |
int j;
|
|
Packit |
dd8086 |
cdio_iso_analysis_t cdio_iso_analysis;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset(&cdio_iso_analysis, 0, sizeof(cdio_iso_analysis));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (j = 2, i = first_data; i <= i_tracks; i++) @{
|
|
Packit |
dd8086 |
lsn_t lsn;
|
|
Packit |
dd8086 |
track_format_t track_format = cdio_get_track_format(p_cdio, i);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
lsn = cdio_get_track_lsn(p_cdio, i);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
switch ( track_format ) @{
|
|
Packit |
dd8086 |
case TRACK_FORMAT_AUDIO:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_ERROR:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case TRACK_FORMAT_CDI:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_XA:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_DATA:
|
|
Packit |
dd8086 |
case TRACK_FORMAT_PSX:
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
start_track = (i == 1) ? 0 : lsn;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* save the start of the data area */
|
|
Packit |
dd8086 |
if (i == first_data)
|
|
Packit |
dd8086 |
data_start = start_track;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* skip tracks which belong to the current walked session */
|
|
Packit |
dd8086 |
if (start_track < data_start + cdio_iso_analysis.isofs_size)
|
|
Packit |
dd8086 |
continue;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fs = cdio_guess_cd_type(p_cdio, start_track, i, &cdio_iso_analysis);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_analysis(cdio_iso_analysis, fs, first_data, num_audio,
|
|
Packit |
dd8086 |
i_tracks, first_track_num, p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( !(CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660 ||
|
|
Packit |
dd8086 |
CDIO_FSTYPE(fs) == CDIO_FS_ISO_HFS ||
|
|
Packit |
dd8086 |
CDIO_FSTYPE(fs) == CDIO_FS_ISO_9660_INTERACTIVE) )
|
|
Packit |
dd8086 |
/* no method for non-ISO9660 multisessions */
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
cdio_destroy(p_cdio);
|
|
Packit |
dd8086 |
return 0;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 4
|
|
Packit |
dd8086 |
@section Example 4: use libiso9660 to extract a file from an ISO-9660 image
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Next a program to show using @command{libiso9660} to extract a file
|
|
Packit |
dd8086 |
from an ISO-9660 image. This can be found in the distribution as
|
|
Packit |
dd8086 |
@file{example/isofile.c}. A more complete and expanded version of this
|
|
Packit |
dd8086 |
is @command{iso-read}, part of this distribution.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
/* This is the ISO 9660 image. */
|
|
Packit |
dd8086 |
#define ISO9660_IMAGE_PATH "../"
|
|
Packit |
dd8086 |
#define ISO9660_IMAGE ISO9660_IMAGE_PATH "test/copying.iso"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define LOCAL_FILENAME "copying"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/iso9660.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_ERRNO_H
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_STRING_H
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
dd8086 |
#include <unistd.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#ifdef HAVE_SYS_TYPES_H
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define my_exit(rc) \
|
|
Packit |
dd8086 |
fclose (p_outfd); \
|
|
Packit |
dd8086 |
free(p_statbuf); \
|
|
Packit |
dd8086 |
iso9660_close(p_iso); \
|
|
Packit |
dd8086 |
return rc; \
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
iso9660_stat_t *p_statbuf;
|
|
Packit |
dd8086 |
FILE *p_outfd;
|
|
Packit |
dd8086 |
int i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
iso9660_t *p_iso = iso9660_open (ISO9660_IMAGE);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_iso) @{
|
|
Packit |
dd8086 |
fprintf(stderr, "Sorry, couldn't open ISO 9660 image %s\n", ISO9660_IMAGE);
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_statbuf = iso9660_ifs_stat_translate (p_iso, LOCAL_FILENAME);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_statbuf)
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
fprintf(stderr,
|
|
Packit |
dd8086 |
"Could not get ISO-9660 file information for file %s\n",
|
|
Packit |
dd8086 |
LOCAL_FILENAME);
|
|
Packit |
dd8086 |
iso9660_close(p_iso);
|
|
Packit |
dd8086 |
return 2;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!(p_outfd = fopen (LOCAL_FILENAME, "wb")))
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
perror ("fopen()");
|
|
Packit |
dd8086 |
free(p_statbuf);
|
|
Packit |
dd8086 |
iso9660_close(p_iso);
|
|
Packit |
dd8086 |
return 3;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Copy the blocks from the ISO-9660 filesystem to the local filesystem. */
|
|
Packit |
dd8086 |
for (i = 0; i < p_statbuf->size; i += ISO_BLOCKSIZE)
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
char buf[ISO_BLOCKSIZE];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset (buf, 0, ISO_BLOCKSIZE);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( ISO_BLOCKSIZE != iso9660_iso_seek_read (p_iso, buf, p_statbuf->lsn
|
|
Packit |
dd8086 |
+ (i / ISO_BLOCKSIZE),
|
|
Packit |
dd8086 |
1) )
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
fprintf(stderr, "Error reading ISO 9660 file at lsn %lu\n",
|
|
Packit |
dd8086 |
(long unsigned int) p_statbuf->lsn + (i / ISO_BLOCKSIZE));
|
|
Packit |
dd8086 |
my_exit(4);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fwrite (buf, ISO_BLOCKSIZE, 1, p_outfd);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (ferror (p_outfd))
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
perror ("fwrite()");
|
|
Packit |
dd8086 |
my_exit(5);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
fflush (p_outfd);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Make sure the file size has the exact same byte size. Without the
|
|
Packit |
dd8086 |
truncate below, the file will a multiple of ISO_BLOCKSIZE.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
if (ftruncate (fileno (p_outfd), p_statbuf->size))
|
|
Packit |
dd8086 |
perror ("ftruncate()");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
my_exit(0);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 5
|
|
Packit |
dd8086 |
@section Example 5: list CD-Text and disc mode info
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Next a program to show using @command{libcdio} to list CD-TEXT data.
|
|
Packit |
dd8086 |
This can be found in the distribution as @file{example/cdtext.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
/* Simple program to list CD-Text info of a Compact Disc using libcdio. */
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/cdtext.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_cdtext_track_info(CdIo_t *p_cdio, track_t i_track, const char *message) @{
|
|
Packit |
dd8086 |
const cdtext_t *cdtext = cdio_get_cdtext(p_cdio, 0);
|
|
Packit |
dd8086 |
if (NULL != cdtext) @{
|
|
Packit |
dd8086 |
cdtext_field_t i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("%s\n", message);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (i=0; i < MAX_CDTEXT_FIELDS; i++) @{
|
|
Packit |
dd8086 |
if (cdtext->field[i]) @{
|
|
Packit |
dd8086 |
printf("\t%s: %s\n", cdtext_field2str(i), cdtext->field[i]);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_disc_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) @{
|
|
Packit |
dd8086 |
track_t i_last_track = i_first_track+i_tracks;
|
|
Packit |
dd8086 |
discmode_t cd_discmode = cdio_get_discmode(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("%s\n", discmode2str[cd_discmode]);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_cdtext_track_info(p_cdio, 0, "\nCD-Text for Disc:");
|
|
Packit |
dd8086 |
for ( ; i_first_track < i_last_track; i_first_track++ ) @{
|
|
Packit |
dd8086 |
char psz_msg[50];
|
|
Packit |
dd8086 |
sprintf(msg, "CD-Text for Track %d:", i_first_track);
|
|
Packit |
dd8086 |
print_cdtext_track_info(p_cdio, i_first_track, psz_msg);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
track_t i_first_track;
|
|
Packit |
dd8086 |
track_t i_tracks;
|
|
Packit |
dd8086 |
CdIo_t *p_cdio;
|
|
Packit |
dd8086 |
cdio = cdio_open (NULL, DRIVER_UNKNOWN);
|
|
Packit |
dd8086 |
i_first_track = cdio_get_first_track_num(p_cdio);
|
|
Packit |
dd8086 |
i_tracks = cdio_get_num_tracks(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_cdio) @{
|
|
Packit |
dd8086 |
printf("Couldn't find CD\n");
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
print_disc_info(p_cdio, i_tracks, i_first_track);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_destroy(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return 0;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 6
|
|
Packit |
dd8086 |
@section Example 6: Using MMC to run an @code{INQURY} command
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Now a program to show issuing a simple MMC command
|
|
Packit |
dd8086 |
(@code{INQUIRY}). This MMC command retrieves the vendor, model and
|
|
Packit |
dd8086 |
firmware revision number of a CD drive. For this command to work,
|
|
Packit |
dd8086 |
usually a CD to be loaded into the drive; odd since the CD itself is
|
|
Packit |
dd8086 |
not used.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This can be found in the distribution as @file{example/mmc1.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
# define __CDIO_CONFIG_H__ 1 /* assumes config.h is libcdio's config.h /
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/scsi_mmc.h>
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Set how long to wait for MMC commands to complete */
|
|
Packit |
dd8086 |
#define DEFAULT_TIMEOUT_MS 10000
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
CdIo_t *p_cdio;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
p_cdio = cdio_open (NULL, DRIVER_UNKNOWN);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL == p_cdio) @{
|
|
Packit |
dd8086 |
printf("Couldn't find CD\n");
|
|
Packit |
dd8086 |
return 1;
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
int i_status; /* Result of MMC command */
|
|
Packit |
dd8086 |
char buf[36] = @{ 0, @}; /* Place to hold returned data */
|
|
Packit |
dd8086 |
scsi_mmc_cdb_t cdb = @{@{0, @}@}; /* Command Descriptor Buffer */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_INQUIRY);
|
|
Packit |
dd8086 |
cdb.field[4] = sizeof(buf);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_status = scsi_mmc_run_cmd(p_cdio, DEFAULT_TIMEOUT_MS,
|
|
Packit |
dd8086 |
&cdb, SCSI_MMC_DATA_READ,
|
|
Packit |
dd8086 |
sizeof(buf), &buf;;
|
|
Packit |
dd8086 |
if (i_status == 0) @{
|
|
Packit |
dd8086 |
char psz_vendor[CDIO_MMC_HW_VENDOR_LEN+1];
|
|
Packit |
dd8086 |
char psz_model[CDIO_MMC_HW_MODEL_LEN+1];
|
|
Packit |
dd8086 |
char psz_rev[CDIO_MMC_HW_REVISION_LEN+1];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memcpy(psz_vendor, buf + 8, sizeof(psz_vendor)-1);
|
|
Packit |
dd8086 |
psz_vendor[sizeof(psz_vendor)-1] = '\0';
|
|
Packit |
dd8086 |
memcpy(psz_model,
|
|
Packit |
dd8086 |
buf + 8 + CDIO_MMC_HW_VENDOR_LEN,
|
|
Packit |
dd8086 |
sizeof(psz_model)-1);
|
|
Packit |
dd8086 |
psz_model[sizeof(psz_model)-1] = '\0';
|
|
Packit |
dd8086 |
memcpy(psz_rev,
|
|
Packit |
dd8086 |
buf + 8 + CDIO_MMC_HW_VENDOR_LEN +CDIO_MMC_HW_MODEL_LEN,
|
|
Packit |
dd8086 |
sizeof(psz_rev)-1);
|
|
Packit |
dd8086 |
psz_rev[sizeof(psz_rev)-1] = '\0';
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("Vendor: %s\nModel: %s\nRevision: %s\n",
|
|
Packit |
dd8086 |
psz_vendor, psz_model, psz_rev);
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
printf("Couldn't get INQUIRY data (vendor, model, and revision\n");
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_destroy(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return 0;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Note the include of @code{#define} of @code{__CDIO_CONFIG_H__} towards
|
|
Packit |
dd8086 |
the beginning. This is useful if the prior @code{#include} of
|
|
Packit |
dd8086 |
@code{config.h} refers to libcdio's configuration header. It indicates
|
|
Packit |
dd8086 |
that libcdio's configuration settings have been used. Without it, you
|
|
Packit |
dd8086 |
may get messages about C Preprocessor symbols getting redefined in the
|
|
Packit |
dd8086 |
@code{#include} of @code{<cdio.cdio.h>}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 7
|
|
Packit |
dd8086 |
@section Example 7: Using the CD Paranoia library for CD-DA reading
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The below program reads CD-DA data. For a more complete program to add
|
|
Packit |
dd8086 |
a WAV header so that the CD can be played from a copy on a hard disk,
|
|
Packit |
dd8086 |
see the corresponding distribution program.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This can be found in the distribution as @file{example/paranoia.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
# define __CDIO_CONFIG_H__ 1 /* assumes config.h is libcdio's config.h /
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <cdio/cdda.h>
|
|
Packit |
dd8086 |
#include <cdio/cd_types.h>
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STDLIB_H
|
|
Packit |
dd8086 |
#include <stdlib.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
cdrom_drive_t *d = NULL; /* Place to store handle given by cd-paranoia. */
|
|
Packit |
dd8086 |
char **ppsz_cd_drives; /* List of all drives with a loaded CDDA in it. */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* See if we can find a device with a loaded CD-DA in it. */
|
|
Packit |
dd8086 |
ppsz_cd_drives = cdio_get_devices_with_cap(NULL, CDIO_FS_AUDIO, false);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (ppsz_cd_drives) @{
|
|
Packit |
dd8086 |
/* Found such a CD-ROM with a CD-DA loaded. Use the first drive in
|
|
Packit |
dd8086 |
the list. */
|
|
Packit |
dd8086 |
d=cdio_cddap_identify(*ppsz_cd_drives, 1, NULL);
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
printf("Unable find or access a CD-ROM drive with an audio CD in it.\n");
|
|
Packit |
dd8086 |
exit(1);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Don't need a list of CD's with CD-DA's any more. */
|
|
Packit |
dd8086 |
cdio_free_device_list(ppsz_cd_drives);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* We'll set for verbose paranoia messages. */
|
|
Packit |
dd8086 |
cdio_cddap_verbose_set(d, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( 0 != cdio_cddap_open(d) ) @{
|
|
Packit |
dd8086 |
printf("Unable to open disc.\n");
|
|
Packit |
dd8086 |
exit(1);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Okay now set up to read up to the first 300 frames of the first
|
|
Packit |
dd8086 |
audio track of the Audio CD. */
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
cdrom_paranoia_t *p = cdio_paranoia_init(d);
|
|
Packit |
dd8086 |
lsn_t i_first_lsn = cdio_cddap_disc_firstsector(d);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( -1 == i_first_lsn ) @{
|
|
Packit |
dd8086 |
printf("Trouble getting starting LSN\n");
|
|
Packit |
dd8086 |
@} else @{
|
|
Packit |
dd8086 |
lsn_t i_cursor;
|
|
Packit |
dd8086 |
track_t i_track = cdio_cddap_sector_gettrack(d, i_first_lsn);
|
|
Packit |
dd8086 |
lsn_t i_last_lsn = cdio_cddap_track_lastsector(d, i_track);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* For demo purposes we'll read only 300 frames (about 4
|
|
Packit |
dd8086 |
seconds). We don't want this to take too long. On the other
|
|
Packit |
dd8086 |
hand, I suppose it should be something close to a real test.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
if ( i_last_lsn - i_first_lsn > 300) i_last_lsn = i_first_lsn + 299;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("Reading track %d from LSN %ld to LSN %ld\n", i_track,
|
|
Packit |
dd8086 |
(long int) i_first_lsn, (long int) i_last_lsn);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Set reading mode for full paranoia, but allow skipping sectors. */
|
|
Packit |
dd8086 |
paranoia_modeset(p, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
paranoia_seek(p, i_first_lsn, SEEK_SET);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for ( i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor ++) @{
|
|
Packit |
dd8086 |
/* read a sector */
|
|
Packit |
dd8086 |
int16_t *p_readbuf=cdio_paranoia_read(p, NULL);
|
|
Packit |
dd8086 |
char *psz_err=cdio_cddap_errors(d);
|
|
Packit |
dd8086 |
char *psz_mes=cdio_cddap_messages(d);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (psz_mes || psz_err)
|
|
Packit |
dd8086 |
printf("%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: "");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (psz_err) cdio_cddap_free_messages(psz_err);
|
|
Packit |
dd8086 |
if (psz_mes) cdio_cddap_free_messages(psz_mes);
|
|
Packit |
dd8086 |
if( !p_readbuf ) @{
|
|
Packit |
dd8086 |
printf("paranoia read error. Stopping.\n");
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
cdio_paranoia_free(p);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_cdda_close(d);
|
|
Packit |
dd8086 |
exit(0);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Those who are die-hard cdparanoia programmers will notice that the
|
|
Packit |
dd8086 |
@value{libcdio} paranoia names are similar but a little bit
|
|
Packit |
dd8086 |
different. In particular instead of @code{paranoia_read} we have above
|
|
Packit |
dd8086 |
@code{cdio_paranoia_read} and instead of @code{cdda_open} we have
|
|
Packit |
dd8086 |
@code{cdio_cddap_open}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This was done intentionally so that it is possible for the original
|
|
Packit |
dd8086 |
paranoia program can co-exist both in source code and linked libraries
|
|
Packit |
dd8086 |
and not conflict with @value{libcdio}'s paranoia source and libraries.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In general in place of any paranoia routine that begins
|
|
Packit |
dd8086 |
@code{paranoia_}, use @code{cdio_paranoia_} and in place of any
|
|
Packit |
dd8086 |
paranoia routine that begins @code{cdda_}, use @code{cdio_cddap_}. But
|
|
Packit |
dd8086 |
for a limited time @value{libcdio} will accept the old paranoia names
|
|
Packit |
dd8086 |
which may be useful for legacy paranoia code. The way this magic works
|
|
Packit |
dd8086 |
is by defining the old paranoia name to be the @value{libcdio} name.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In the unusual case where you do want to use both the original
|
|
Packit |
dd8086 |
paranoia and @value{libcdio} routines in a single source, the C
|
|
Packit |
dd8086 |
preprocessor symbol @code{DO_NOT_WANT_PARANOIA_COMPATIBILITY} can be
|
|
Packit |
dd8086 |
@code{define}'d and this disables the @code{#define} substitution done
|
|
Packit |
dd8086 |
automatically. The may still be a problem with conflicting structure
|
|
Packit |
dd8086 |
definitions like @code{cdrom_drive_t}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Example 8
|
|
Packit |
dd8086 |
@section Example 8: Setting output verbosity
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Sometimes in tracking down a problem in your code or libcdio's you may
|
|
Packit |
dd8086 |
want more information about what is going on inside the
|
|
Packit |
dd8086 |
@command{libcdio} library.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The setting global variable @code{cdio_loglevel_default} defined in
|
|
Packit |
dd8086 |
header file @code{<cdio/logging.h>} controls the verbosity level. By
|
|
Packit |
dd8086 |
default, only warnings, errors, and fatal errors are printed. However
|
|
Packit |
dd8086 |
by setting this variable you can get either debug or informational
|
|
Packit |
dd8086 |
messages, or cause the normal messages that appear to be suppressed.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The verbosity levels defined in the library are from lowest number to
|
|
Packit |
dd8086 |
highest are:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@table @code
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{CDIO_LOG_DEBUG} (value 1)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
These are of a debugging nature and are give the most verbose output.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{CDIO_LOG_INFO} (value 2)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
These are informational message.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{CDIO_LOG_WARN} (value 3)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
These are warning message. Not an error, per se, but something that
|
|
Packit |
dd8086 |
might be of concern.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{CDIO_LOG_ERROR} (value 4)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
These are error messages that force program termination.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{CDIO_LOG_ASSERT} (value 5)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
These are error messages that represent an internal inconsistency in
|
|
Packit |
dd8086 |
the @command{libcdio} library. In the absence of @command{libcdio}
|
|
Packit |
dd8086 |
bugs, these should never appear.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end table
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Setting a lower or more verbose log level will cause higher-level
|
|
Packit |
dd8086 |
messages to appear, but not those that are less than the set verbosity
|
|
Packit |
dd8086 |
level. The ``debug'' level is the lowest. So setting
|
|
Packit |
dd8086 |
@code{cdio_loglevel_default} to level causes all other levels of
|
|
Packit |
dd8086 |
messages to be displayed. However setting the verbosity level to
|
|
Packit |
dd8086 |
``warn'' will cause debug and informational messages (lower
|
|
Packit |
dd8086 |
level messages) to be ignored while still showing warning, error, and
|
|
Packit |
dd8086 |
fatal error messages.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another thing that can be done is to write a custom log handler that
|
|
Packit |
dd8086 |
will be used instead of @command{libcdio}'s default handlers. Using
|
|
Packit |
dd8086 |
this, you have complete control of how you want logging to be handled.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Here is an example adapted from example program @command{logging.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@smallexample
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#include <stdlib.h>
|
|
Packit |
dd8086 |
#include <sys/types.h>
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#include <limits.h>
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/cd_types.h>
|
|
Packit |
dd8086 |
#include <cdio/logging.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Here is an example of a custom log handler. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
custom_log_handler (cdio_log_level_t level, const char *message)
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
switch(level) @{
|
|
Packit |
dd8086 |
case CDIO_LOG_DEBUG:
|
|
Packit |
dd8086 |
printf("-- custom debug message: %s\n", message);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
case CDIO_LOG_INFO:
|
|
Packit |
dd8086 |
printf("-- custom info message: %s\n", message);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
case CDIO_LOG_WARN:
|
|
Packit |
dd8086 |
printf("-- custom warning message: %s\n", message);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
case CDIO_LOG_ERROR:
|
|
Packit |
dd8086 |
printf("-- custom error message: %s\n", message);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
case CDIO_LOG_ASSERT:
|
|
Packit |
dd8086 |
printf("-- custom fatal error message: %s\n", message);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
printf("custom level %d message: %s\n", level, message);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_drives()
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
char **ppsz_cd_drives=NULL, **c;
|
|
Packit |
dd8086 |
/* Print out a list of CD-drives with the above set log level. */
|
|
Packit |
dd8086 |
ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE);
|
|
Packit |
dd8086 |
if (NULL != ppsz_cd_drives)
|
|
Packit |
dd8086 |
for( c = ppsz_cd_drives; *c != NULL; c++ ) @{
|
|
Packit |
dd8086 |
printf("-- Drive %s\n", *c);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
cdio_free_device_list(ppsz_cd_drives);
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, const char *argv[])
|
|
Packit |
dd8086 |
@{
|
|
Packit |
dd8086 |
/* Set the log level to the warning verbosity. */
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_WARN;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_drives();
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Do the same thing again but with a custom log handler. */
|
|
Packit |
dd8086 |
cdio_log_set_handler (custom_log_handler);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
print_drives();
|
|
Packit |
dd8086 |
return 0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@}
|
|
Packit |
dd8086 |
@end smallexample
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node All sample programs
|
|
Packit |
dd8086 |
@section A list of all sample programs in the @code{example} directory
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The @code{example} directory contains some simple examples of the use
|
|
Packit |
dd8086 |
of the @value{libcdio} library.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A larger more-complicated example are the @command{cd-drive},
|
|
Packit |
dd8086 |
@command{cd-info}, @command{cd-read}, @command{iso-info} and
|
|
Packit |
dd8086 |
@command{iso-info} programs in the @command{src} directory.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Descriptions of the sample are as follows...
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@table @code
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{audio.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show audio controls.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{cdchange.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to test if a CD has been changed since the last change test.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{cd-eject.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A a stripped-down "eject" command to open or close a CD-ROM tray.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{cdtext.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show CD-Text and CD disc mode info.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{drives.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show drivers installed and what the default CD-ROM drive
|
|
Packit |
dd8086 |
is and what CD drives are available.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{eject.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program eject a CD from a CD-ROM drive and then close the door again.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{isofile.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libiso9660 to extract a file from an ISO-9660 image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{isofile2.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libiso9660 to extract a file from a CDRWIN cue/bin CD image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{C++/isofile2.cpp}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The same program as @code{isofile2.c} written in C++.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{isofuzzy.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program showing fuzzy ISO-9660 detection/reading.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{isolist.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using @code{libiso9660} to list files in a
|
|
Packit |
dd8086 |
directory of an ISO-9660 image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{C++/isolist.cpp}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The same program as @code{isolist.c} written in C++.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{isofuzzy.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program showing fuzzy ISO-9660 detection/reading.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{logging.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show to to set log verbosity levels and how to write a
|
|
Packit |
dd8086 |
custom log handler.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{mmc1.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show issuing a simple MMC command (@code{INQUIRY}).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{C++/mmc1.cpp}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The same program as @code{mmc1.c} written in C++.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{mmc2.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A more involved MMC command to list CD and drive features from a
|
|
Packit |
dd8086 |
SCSI-MMC @code{GET_CONFIGURATION} command.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{mmc2a.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Prints MMC @command{MODE_SENSE} page 2A parameters.
|
|
Packit |
dd8086 |
Page 2a are the CD/DVD Capabilities and Mechanical Status.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{C++/mmc2.cpp}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The same program as @code{mmc2.c} written in C++.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{paranoia.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libcdio's version of the CD-DA paranoia.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{paranoia2.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libcdio's version of the CD-DA paranoia
|
|
Packit |
dd8086 |
library. But in this version, we'll open a cdio object before calling
|
|
Packit |
dd8086 |
paranoia's open. I imagine in many cases such as media players this
|
|
Packit |
dd8086 |
may be what will be done since, one may want to get CDDB/CD-Text info
|
|
Packit |
dd8086 |
beforehand.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{tracks.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A simple program to list track numbers and logical sector numbers of a
|
|
Packit |
dd8086 |
Compact Disc using @value{libcdio}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{sample2.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A simple program to show drivers installed and what the default CD-ROM
|
|
Packit |
dd8086 |
drive is.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{sample3.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A simple program to show the use of @code{cdio_guess_cd_type()}. Figures out
|
|
Packit |
dd8086 |
the kind of CD image we've got.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{sample4.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A slightly improved sample3 program: we handle cdio logging and take
|
|
Packit |
dd8086 |
an optional CD-location.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{udf1.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libudf to list files in a directory of an UDF
|
|
Packit |
dd8086 |
image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{udf2.c}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A program to show using libudf to extract a file from an UDF image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end table
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Utility Programs
|
|
Packit |
dd8086 |
@chapter Diagnostic programs: @command{cd-drive}, @command{cd-info}, @command{cd-read}, @command{iso-info}, @command{iso-read}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* cd-drive:: list out CD-ROM drive information
|
|
Packit |
dd8086 |
* cd-info:: list out CD or CD-image information
|
|
Packit |
dd8086 |
* cd-read:: read blocks of a CD or CD image
|
|
Packit |
dd8086 |
* iso-info:: list out ISO-9600 image information
|
|
Packit |
dd8086 |
* iso-read:: extract a file from an ISO 9660 image
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node cd-drive
|
|
Packit |
dd8086 |
@section @samp{cd-drive}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@samp{cd-drive} lists out drive information, what features drive
|
|
Packit |
dd8086 |
supports, and information about what hardware drivers are available.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node cd-info
|
|
Packit |
dd8086 |
@section @samp{cd-info}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@samp{cd-info} will print out the structure of a CD medium which could
|
|
Packit |
dd8086 |
either be a Compact Disc in a CD ROM or an CD image. It can try to
|
|
Packit |
dd8086 |
analyze the medium to give characteristics of the medium, such as how
|
|
Packit |
dd8086 |
many tracks are in the CD and the format of each track, whether a CD
|
|
Packit |
dd8086 |
contains a Video CD, CD-DA, PhotoCD, whether a track has an ISO-9660
|
|
Packit |
dd8086 |
filesystem.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node cd-read
|
|
Packit |
dd8086 |
@section @samp{cd-read}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@samp{cd-info} can be used to read blocks a CD medium which could
|
|
Packit |
dd8086 |
either be a Compact Disc in a CD ROM or an CD image. You specify the
|
|
Packit |
dd8086 |
beginning and ending LSN and what mode format to use in the reading.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node iso-info
|
|
Packit |
dd8086 |
@section @samp{iso-info}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@samp{iso-info} can be used to print out the structure of an ISO 9660
|
|
Packit |
dd8086 |
image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node iso-read
|
|
Packit |
dd8086 |
@section @samp{iso-read}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@samp{iso-read} can be used to extract a file in an ISO-9660 image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node CD-ROM Access and Drivers
|
|
Packit |
dd8086 |
@chapter CD-ROM Access and Drivers
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* SCSI mess:: SCSI, SCSI commands, and MMC commands
|
|
Packit |
dd8086 |
* Access Modes:: Access Modes
|
|
Packit |
dd8086 |
* Accessing Driver Parameters:: Accessing Driver Parameters
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
* GNU/Linux:: GNU/Linux ioctl
|
|
Packit |
dd8086 |
* Microsoft:: Microsoft Windows ioctl and ASPI
|
|
Packit |
dd8086 |
* Solaris:: Solaris ATAPI and SCSI
|
|
Packit |
dd8086 |
* FreeBSD:: FreeBSD ioctl and CAM
|
|
Packit |
dd8086 |
* OS X:: OSX (non-exclussive access)
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node SCSI mess
|
|
Packit |
dd8086 |
@section SCSI, SCSI commands, and MMC commands
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Historically, SCSI referred to a class of hardware devices and device
|
|
Packit |
dd8086 |
controllers, bus technology and the data cables and protocols which
|
|
Packit |
dd8086 |
attached to such devices. This is now called ``Parallel SCSI''.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A specification standard grew out of the @emph{commands} that
|
|
Packit |
dd8086 |
controlled such SCSI devices, but now covers a wider variety of bus
|
|
Packit |
dd8086 |
technologies including Parallel SCSI, ATA/ATAPI, Serial ATA, Universal
|
|
Packit |
dd8086 |
Serial Bus (USB versions 1.1 and 2.0), and High Performance Serial Bus
|
|
Packit |
dd8086 |
(IEEE 1394, 1394A, and 1394B).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another similar class of hardware devices and controllers is called ATA
|
|
Packit |
dd8086 |
and a command interface to that is called ATAPI (ATA Packetized
|
|
Packit |
dd8086 |
Interface). ATAPI provides a mechanism for transferring and executing
|
|
Packit |
dd8086 |
SCSI commands.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
MMC (Multimedia commands) is a specification which adds special SCSI
|
|
Packit |
dd8086 |
commands for CD, DVD, Blu-Ray devices.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If your optical drive understands MMC commands as most do nowadays,
|
|
Packit |
dd8086 |
this probably gives the most flexibility in control. SCSI and ATAPI
|
|
Packit |
dd8086 |
CD-ROM devices generally support a fairly large set of MMC
|
|
Packit |
dd8086 |
commands. Unfortunately, on most Operating Systems one may need to do
|
|
Packit |
dd8086 |
some additional setup, such as install drivers or modules, to allow
|
|
Packit |
dd8086 |
access in this manner.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The name ``SCSI MMC'' is often found in the literature in
|
|
Packit |
dd8086 |
specifications and on the Internet. The ``SCSI'' part is probably a
|
|
Packit |
dd8086 |
little bit misleading because a drive can understand ``SCSI MMC''
|
|
Packit |
dd8086 |
commands but not use a SCSI bus protocol---ATAPI CD-ROMs are one such
|
|
Packit |
dd8086 |
broad class of examples. In fact there are drivers to ``encapsulate''
|
|
Packit |
dd8086 |
non-SCSI drives to make them act like more like SCSI drives, such as
|
|
Packit |
dd8086 |
by adding SCSI address naming.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For clarity and precision we will use the term ``MMC'' rather than
|
|
Packit |
dd8086 |
``SCSI MMC''.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
One of the problems with MMC is that there are so many different
|
|
Packit |
dd8086 |
``standards''. In particular:
|
|
Packit |
dd8086 |
@itemize
|
|
Packit |
dd8086 |
@item MMC --- @url{ftp://ftp.t10.org/t10/drafts/mmc/},
|
|
Packit |
dd8086 |
@item MMC 2 --- @url{ftp://ftp.t10.org/t10/drafts/mmc2/}
|
|
Packit |
dd8086 |
@item MMC 3 --- @url{ftp://ftp.t10.org/t10/drafts/mmc3/}
|
|
Packit |
dd8086 |
@item MMC 4 --- @url{ftp://ftp.t10.org/t10/drafts/mmc4/}
|
|
Packit |
dd8086 |
@item MMC 5 --- @url{ftp://ftp.t10.org/t10/drafts/mmc5/}
|
|
Packit |
dd8086 |
@end itemize
|
|
Packit |
dd8086 |
along with the several ``drafts'' of these.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another problem with the MMC commands related to the variations in
|
|
Packit |
dd8086 |
standards is the variation in the commands themselves and there are
|
|
Packit |
dd8086 |
perhaps two or three ways to do many of the basic commands like read a
|
|
Packit |
dd8086 |
CD frame.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There seems to be a fascination with the number of bytes a command
|
|
Packit |
dd8086 |
takes in the MMC-specification world. (Size matters?) So often the
|
|
Packit |
dd8086 |
name of an operation will have a suffix with the number of bytes of
|
|
Packit |
dd8086 |
the command (actually in MMC jargon this is called a ``CDB''
|
|
Packit |
dd8086 |
@cindex CDB (Command Descriptor Block)
|
|
Packit |
dd8086 |
or command descriptor block). So for example there is a 6-byte ``MODE
|
|
Packit |
dd8086 |
SELECT'' often called ``MODE SELECT 6'' and a 10-byte ``MODE SELECT''
|
|
Packit |
dd8086 |
often called ``MODE SELECT 10''. Presumably the 6-byte command came
|
|
Packit |
dd8086 |
first and it was discovered that there was some deficiency causing the
|
|
Packit |
dd8086 |
longer command. In @value{libcdio} where there are two formats we add
|
|
Packit |
dd8086 |
the suffix in the name, e.g. @code{CDIO_MMC_GPCMD_MODE_SELECT_6} or
|
|
Packit |
dd8086 |
@code{CDIO_MMC_GPCMD_MODE_SELECT_10}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If the fascination and emphasis in the MMC specifications of CDB size
|
|
Packit |
dd8086 |
is a bit odd, equally so is the fact that this too often has bled
|
|
Packit |
dd8086 |
through at the OS programming API. However in @value{libcdio}, you
|
|
Packit |
dd8086 |
just give the opcode in @code{scsi_mmc_run_cmd()} and we'll do the
|
|
Packit |
dd8086 |
work to figure out how many bytes of the CDB are used.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Down the line it is hoped that @value{libcdio} will have a way to
|
|
Packit |
dd8086 |
remove a distinction between the various alternative and
|
|
Packit |
dd8086 |
alternative-size MMC commands. In @code{cdio/scsi-mmc.h} you will
|
|
Packit |
dd8086 |
find a little bit of this for example via the routine
|
|
Packit |
dd8086 |
@code{scsi_mmc_get_drive_cap()}. However much more work is needed.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Finally, in @code{libcdio} there is a driver access mode (not a
|
|
Packit |
dd8086 |
driver) called ``MMC''. It tells the specific drivers to use MMC
|
|
Packit |
dd8086 |
commands instead of other OS-specific mechanisms.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Access Modes
|
|
Packit |
dd8086 |
@section Access Modes
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There are serveral ways that you can open a CD-ROM drive for
|
|
Packit |
dd8086 |
subsequent use. Each way is called an @emph{access
|
|
Packit |
dd8086 |
mode}. Historically libcdio only supported a reading kind of
|
|
Packit |
dd8086 |
access.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Adding the abilty to writing to a drive for ``burning'' is being added
|
|
Packit |
dd8086 |
by Thomas Schmitt, and this is accomplished by opening the drive in a
|
|
Packit |
dd8086 |
read-write mode. Currently writing modes are only supported via the
|
|
Packit |
dd8086 |
MMC command interface. Under this, one can get exclusive read-write
|
|
Packit |
dd8086 |
access or non-exclusive read-write access. The names of these two
|
|
Packit |
dd8086 |
modes are @code{MMC_RDWR_EXCL} and @code{MMC_RDWR} respectively.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
On various OS's often there are two kinds of read modes that are
|
|
Packit |
dd8086 |
supported, one which uses MMC commands and one which uses some sort of
|
|
Packit |
dd8086 |
OS-specific native command interface. For example on Unix, there is
|
|
Packit |
dd8086 |
often a access mode associated with issuing an device-specific
|
|
Packit |
dd8086 |
@code{ioctl}'s that the OS supports.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
To specify a particular kind of access mode, use @code{cdio_open_am}
|
|
Packit |
dd8086 |
which is like @code{cdio_open} but it requires one to specify an
|
|
Packit |
dd8086 |
access mode.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Accessing Driver Parameters
|
|
Packit |
dd8086 |
@section Accessing Driver Parameters --- @code{cdio_get_arg}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Once a driver is opened, you can use call @code{cdio_get_arg} to get
|
|
Packit |
dd8086 |
information about the driver. Each driver can have specific features
|
|
Packit |
dd8086 |
that can be queried, but there are features that are common to all
|
|
Packit |
dd8086 |
drivers. These are listed below:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@table @code
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{access-mode}
|
|
Packit |
dd8086 |
This returns a string which is the name of the access mode in use.
|
|
Packit |
dd8086 |
@item @code{mmc-supported?}
|
|
Packit |
dd8086 |
This returns a string ``true'' or ``false'' depending whether the
|
|
Packit |
dd8086 |
driver with this access mode support MMC commands.
|
|
Packit |
dd8086 |
@item @code{scsi-tuple}
|
|
Packit |
dd8086 |
On drivers that support MMC commands, this returns the SCSI name or a
|
|
Packit |
dd8086 |
faked-up SCSI name that ripping front ends typically use.
|
|
Packit |
dd8086 |
@end table
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node GNU/Linux
|
|
Packit |
dd8086 |
@section GNU/Linux
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The GNU/Linux uses a hybrid of methods. Somethings are done via ioctl
|
|
Packit |
dd8086 |
and some things via MMC. GNU/Linux has a rather nice and complete
|
|
Packit |
dd8086 |
ioctl mechanism. On the other hand, the MMC mechanism is more
|
|
Packit |
dd8086 |
universal. There are other ``access modes'' listed which are not
|
|
Packit |
dd8086 |
really access modes and should probably be redone/rethought. They are
|
|
Packit |
dd8086 |
just different ways to run the read command. But for completeness
|
|
Packit |
dd8086 |
These are ``READ_CD'' and ``READ_10''.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Writing/burning to a drive is supported via access modes
|
|
Packit |
dd8086 |
@code{MMC_RDWR_EXCL} or @code{MMC_RDWR}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Microsoft
|
|
Packit |
dd8086 |
@section Microsoft Windows ioctl and ASPI
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There are two CD drive access methods on Microsoft Windows platforms:
|
|
Packit |
dd8086 |
ioctl and ASPI.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The ASPI interface specification was developed by Adaptec for sending
|
|
Packit |
dd8086 |
commands to a SCSI host adapter (such as those controlling CD and DVD
|
|
Packit |
dd8086 |
drives) and used on Window 9x/NT and later. Emulation for ATAPI drives
|
|
Packit |
dd8086 |
was added so that the same sets of commands worked those even though
|
|
Packit |
dd8086 |
the drives might not be SCSI nor might there even be a SCSI controller
|
|
Packit |
dd8086 |
attached. The DLL is not part of Microsoft Windows and has to be
|
|
Packit |
dd8086 |
downloaded and installed separately.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
However in Windows NT/2K/XP, Microsoft provides their Win32 ioctl
|
|
Packit |
dd8086 |
interface, and has taken steps to make using ASPI more inaccessible
|
|
Packit |
dd8086 |
(e.g. requiring administrative access to use ASPI).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Solaris
|
|
Packit |
dd8086 |
@section Solaris ATAPI and SCSI
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There is currently only one CD drive access methods in Solaris: SCSI
|
|
Packit |
dd8086 |
(called ``USCSI'' or ``user SCSI'' in Solaris). There used to be an
|
|
Packit |
dd8086 |
ATAPI method and it could be resurrected if needed. USCSI was
|
|
Packit |
dd8086 |
preferred since on newer releases of Solaris and Solaris environments
|
|
Packit |
dd8086 |
one need to have root access for ATAPI.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node FreeBSD
|
|
Packit |
dd8086 |
@section FreeBSD ioctl and CAM
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There are two classes of access methods on FreeBSD: ioctl and CAM
|
|
Packit |
dd8086 |
(common access method). CAM is preferred when possible, especially on
|
|
Packit |
dd8086 |
newer releases. However CAM is right now sort of a hybrid and includes
|
|
Packit |
dd8086 |
some ioctl code.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Writing/burning to a drive is supported via access modes
|
|
Packit |
dd8086 |
@code{MMC_RDWR_EXCL} or @code{MMC_RDWR} which underneath use CAM access.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node OS X
|
|
Packit |
dd8086 |
@section OS X (non-exclusive access)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A problem with libcdio on OS/X is that if the OS thinks it understands
|
|
Packit |
dd8086 |
the drive, it will get exclusive access to the drive and thus prevents
|
|
Packit |
dd8086 |
a library like this from obtaining non-exclusive access.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Currently @value{libcdio} access the CD-ROM non-exclusively. However
|
|
Packit |
dd8086 |
in order to be able to issue MMC, the current belief is that
|
|
Packit |
dd8086 |
exclusive access is needed. Probably in a future @value{libcdio},
|
|
Packit |
dd8086 |
there will be some way to specify which kind of access is desired
|
|
Packit |
dd8086 |
(with the inherent consequences of each).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
More work on this driver is needed. Volunteers?
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Internal Program Organization
|
|
Packit |
dd8086 |
@chapter Internal Program Organization
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* File Organization::
|
|
Packit |
dd8086 |
* Library Organization::
|
|
Packit |
dd8086 |
* Programming Conventions::
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node File Organization
|
|
Packit |
dd8086 |
@section File Organization
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Here is a list of @value{libcdio} directories.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@itemize
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{include/cdio}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This contains the headers that are public. One that will probably be
|
|
Packit |
dd8086 |
used quite a bit is @code{<cdio/cdio.h>}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{lib}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Code for installed libraries. See below for further breakout
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{lib/driver}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Code for various OS-specific CD-ROM drivers, image drivers, and
|
|
Packit |
dd8086 |
common MMC routines.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This code comprises @code{libcdio.a} (or the shared version of it).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{lib/iso9660}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Code for to extract or query ISO-9660 images.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This code comprises @code{libiso9660.a} (or the shared version of it).
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{lib/paranoia}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This is from cdparanoia. It is the OS- and hardware- dependent code to
|
|
Packit |
dd8086 |
detect and correct jitter for CD-DA CDs.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{lib/cdda_interface}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This is also from cdparanoia. It is the OS- and hardware- independent
|
|
Packit |
dd8086 |
code to detect and correct jitter for CD-DA CDs.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{doc}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A home for fine documentation such as this masterpiece.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{example}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Here you will find various small example programs using
|
|
Packit |
dd8086 |
@value{libcdio} which are largely for pedagogical purposes. You might
|
|
Packit |
dd8086 |
be able to find one that is similar to what you want to do that could
|
|
Packit |
dd8086 |
be extended. In fact some these are contain the kernel ideas behind of
|
|
Packit |
dd8086 |
some of the larger programs in @file{src}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{src}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Various stand-alone utility programs. See below.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{src/paranoia}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@value{libcdio}'s version of @code{cdparanoia}. Except for the fact
|
|
Packit |
dd8086 |
that the back-end CD-reading code has been replaced by
|
|
Packit |
dd8086 |
@value{libcdio}'s routines the code is pretty much identical.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{test}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Regression tests
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{test/data}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Disk images and image meta-data used in tests
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{test/driver}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Unit tests centered around the libcdio library (@code{libcdio}, source
|
|
Packit |
dd8086 |
location @code{lib/driver}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end itemize
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Library Organization
|
|
Packit |
dd8086 |
@section Library Organization
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* libcdio::
|
|
Packit |
dd8086 |
* libcdio_cdda:: Access to CD-DA via the CD Paranoia library
|
|
Packit |
dd8086 |
* libcdio_paranoia:: Access to the CD Paranoia library
|
|
Packit |
dd8086 |
* libiso9660:: Access to ISO 9660 file systems and structures
|
|
Packit |
dd8086 |
* libudf:: Access to UDF file systems and structures
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node libcdio
|
|
Packit |
dd8086 |
@subsection @samp{libcdio}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@value{libcdio} exports one opaque type @code{CdIo_t}. Internally this
|
|
Packit |
dd8086 |
a structure containing an enumeration for the driver, a structure
|
|
Packit |
dd8086 |
containing function pointers and a generic ``environment'' pointer
|
|
Packit |
dd8086 |
which is passed as a parameter on a function call. See
|
|
Packit |
dd8086 |
@file{lib/driver/cdio_private.h}. The initialization routine for each
|
|
Packit |
dd8086 |
driver sets up the function pointers and allocates memory for the
|
|
Packit |
dd8086 |
environment. When a particular user-level cdio routine is called (e.g
|
|
Packit |
dd8086 |
@code{cdio_get_first_track_num} for lib/driver/track.c), the
|
|
Packit |
dd8086 |
environment pointer is passed to a device-specific routine which will
|
|
Packit |
dd8086 |
then cast this pointer into something of the appropriate type.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Because function pointers are used, there can be and is quite a bit
|
|
Packit |
dd8086 |
of sharing of common routines. Some of the common routines are found
|
|
Packit |
dd8086 |
in the file @file{lib/driver/_cdio_generic.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Another set of routines that one is likely to find shared amongst
|
|
Packit |
dd8086 |
drivers are the MMC commands. These are located in
|
|
Packit |
dd8086 |
@file{lib/driver/scsi_mmc.c}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There is not only an attempt to share functions but we've tried to create
|
|
Packit |
dd8086 |
a generic CD structure @code{generic_img_private_t} of file
|
|
Packit |
dd8086 |
@file{lib/driver/generic.h}. By putting information into a common
|
|
Packit |
dd8086 |
structure, we increase the likelihood of being able to have a common
|
|
Packit |
dd8086 |
routine to perform some sort of function.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
The generic CD structure would also be useful in a utility to convert
|
|
Packit |
dd8086 |
one CD-image format to another. Basically the first image format is
|
|
Packit |
dd8086 |
``parsed'' into the common internal format and then from this
|
|
Packit |
dd8086 |
structure it is not parsed.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node libcdio_cdda
|
|
Packit |
dd8086 |
@subsection @samp{libcdio_cdda}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This library is intended to give access CD-DA disks using Monty's
|
|
Packit |
dd8086 |
cd-paranoia library underneath.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
To be completed....
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node libcdio_paranoia
|
|
Packit |
dd8086 |
@subsection @samp{libcdio_paranoia}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This library is intended to give access Monty's cd-paranoia
|
|
Packit |
dd8086 |
library. It is the gap detection and jitter correction part without
|
|
Packit |
dd8086 |
the part dealing with CD-DA reading.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
To be completed....
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node libiso9660
|
|
Packit |
dd8086 |
@subsection @samp{libiso9660}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This library is intended to give access and manipulate a ISO-9600 file
|
|
Packit |
dd8086 |
image. One part of it is concerned with the the entire ISO-9660 file
|
|
Packit |
dd8086 |
system image, and the other part access routines for manipulating data
|
|
Packit |
dd8086 |
structures and fields that go into such an image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
To be completed....
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node libudf
|
|
Packit |
dd8086 |
@subsection @samp{libudf}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This library is intended to give access and manipulate a UDF file
|
|
Packit |
dd8086 |
image.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
To be completed....
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Programming Conventions
|
|
Packit |
dd8086 |
@section Programming Conventions
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* Coding Conventions::
|
|
Packit |
dd8086 |
* Namespace Conventions::
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Coding Conventions
|
|
Packit |
dd8086 |
@subsection Coding Conventions
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
In @value{libcdio} there are a number of conventions used. If you
|
|
Packit |
dd8086 |
understand some of these conventions it may facilitate understanding
|
|
Packit |
dd8086 |
the code a little.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Namespace Conventions
|
|
Packit |
dd8086 |
@subsection Namespace Conventions
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For the most part, the visible external @value{libcdio} names follow
|
|
Packit |
dd8086 |
conventions so as not to be confused with other applications or
|
|
Packit |
dd8086 |
libraries. If you understand these conventions, there will be little
|
|
Packit |
dd8086 |
or no chance that the names you use will conflict with @value{libcdio}
|
|
Packit |
dd8086 |
and @code{libiso9660} and vice versa.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
All of the external @value{libcdio} C routines start out with
|
|
Packit |
dd8086 |
@code{cdio_}, e.g. @code{cdio_open}; as a corollary, the
|
|
Packit |
dd8086 |
@value{libcdio} CD-Paranoia routines start @code{cdio_cddap_},
|
|
Packit |
dd8086 |
e.g. @code{cdio_cddap_open}. @code{libiso9660} routines start
|
|
Packit |
dd8086 |
@code{iso9660_}, e.g. @code{iso9660_open}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@value{libcdio} C-Preprocessor names generally start @code{CDIO_}, for
|
|
Packit |
dd8086 |
example @code{CDIO_CD_FRAMESIZE_RAW}; @code{libiso9660}
|
|
Packit |
dd8086 |
C-preprocessor names start @code{ISO9660_},
|
|
Packit |
dd8086 |
e.g. @code{ISO9660_FRAMESIZE}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@subsubsection suffixes (type and structure names)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A few suffixes are used in type and structure names:
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@itemize
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{_e}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
An enumeration tag. Generally though the same name will appear with the
|
|
Packit |
dd8086 |
@code{_t} suffix and probably that should be used instead.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{_s}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A structure tag. Generally though the same name will appear with the
|
|
Packit |
dd8086 |
@code{_t} suffix and probably that should be used instead.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{_t}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A type suffix.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end itemize
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@subsubsection prefixes (variable names)
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A number of prefixes are used in variable names here's what they mean
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@itemize
|
|
Packit |
dd8086 |
@item @code{i_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
An integer type of some sort. A variable of this ilk one might find
|
|
Packit |
dd8086 |
being iterated over in @code{for} loops or used as the index of an
|
|
Packit |
dd8086 |
array for example.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{b_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A Boolean type of some sort. A variable of this ilk one might find
|
|
Packit |
dd8086 |
being in an @code{if} condition for example.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{p_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A pointer of some sort. A variable of this ilk, say
|
|
Packit |
dd8086 |
@code{p_foo} one is like likely to see @code{*p_foo} or
|
|
Packit |
dd8086 |
@code{p_foo->...}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{pp_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A pointer to a pointer of some sort. A variable of this ilk, say
|
|
Packit |
dd8086 |
@code{pp_foo} one is like likely to see @code{**p_foo} or
|
|
Packit |
dd8086 |
@code{p_foo[x][y]} for example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{psz_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A @code{char *} pointer of some sort. A variable of this ilk, say
|
|
Packit |
dd8086 |
@code{psz_foo} may be used in a string operation. For example
|
|
Packit |
dd8086 |
@code{printf(%s\n", psz_foo)} or @code{strdup(psz_foo)}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@item @code{ppsz_}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
A pointer to a @code{char *} pointer of some sort. A variable of this
|
|
Packit |
dd8086 |
ilk, say @code{ppsz_foo} is used for example to return a list of
|
|
Packit |
dd8086 |
CD-ROM device names
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@end itemize
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
There are a some other naming conventions. Generally if a routine
|
|
Packit |
dd8086 |
name starts @code{cdio_}, e.g. @code{cdio_open}, then it is an
|
|
Packit |
dd8086 |
externally visible routine in @code{libcdio}. If a name starts
|
|
Packit |
dd8086 |
@code{iso9660_}, e.g. @code{iso9660_is_dchar} then it is an externally
|
|
Packit |
dd8086 |
visible routine in @code{libiso9660}. If a name starts
|
|
Packit |
dd8086 |
@code{scsi_mmc_}, e.g. @code{scsi_mmc_get_discmode}, then it is an
|
|
Packit |
dd8086 |
externally visible MMC routine. (We don't have a separate library for
|
|
Packit |
dd8086 |
this yet.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Names using entirely capital letters and that start @code{CDIO_} are
|
|
Packit |
dd8086 |
externally visible @code{#defines}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO-9660 Character Sets
|
|
Packit |
dd8086 |
@appendix ISO-9660 Character Sets
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
For a description of where are used see @xref{ISO 9660 Level 1}.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@menu
|
|
Packit |
dd8086 |
* ISO646 d-Characters::
|
|
Packit |
dd8086 |
* ISO646 a-Characters::
|
|
Packit |
dd8086 |
@end menu
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO646 d-Characters
|
|
Packit |
dd8086 |
@appendixsec ISO646 d-Characters
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@example
|
|
Packit |
dd8086 |
| 0 1 2 3 4 5 6 7
|
|
Packit |
dd8086 |
--+-----------------
|
|
Packit |
dd8086 |
0 | 0 P
|
|
Packit |
dd8086 |
1 | 1 A Q
|
|
Packit |
dd8086 |
2 | 2 B R
|
|
Packit |
dd8086 |
3 | 3 C S
|
|
Packit |
dd8086 |
4 | 4 D T
|
|
Packit |
dd8086 |
5 | 5 E U
|
|
Packit |
dd8086 |
6 | 6 F V
|
|
Packit |
dd8086 |
7 | 7 G W
|
|
Packit |
dd8086 |
8 | 8 H X
|
|
Packit |
dd8086 |
9 | 9 I Y
|
|
Packit |
dd8086 |
a | J Z
|
|
Packit |
dd8086 |
b | K
|
|
Packit |
dd8086 |
c | L
|
|
Packit |
dd8086 |
d | M
|
|
Packit |
dd8086 |
e | N
|
|
Packit |
dd8086 |
f | O _
|
|
Packit |
dd8086 |
@end example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node ISO646 a-Characters
|
|
Packit |
dd8086 |
@appendixsec ISO646 a-Characters
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@example
|
|
Packit |
dd8086 |
| 0 1 2 3 4 5 6 7
|
|
Packit |
dd8086 |
--+-----------------
|
|
Packit |
dd8086 |
0 | 0 P
|
|
Packit |
dd8086 |
1 | ! 1 A Q
|
|
Packit |
dd8086 |
2 | " 2 B R
|
|
Packit |
dd8086 |
3 | 3 C S
|
|
Packit |
dd8086 |
4 | 4 D T
|
|
Packit |
dd8086 |
5 | % 5 E U
|
|
Packit |
dd8086 |
6 | & 6 F V
|
|
Packit |
dd8086 |
7 | ' 7 G W
|
|
Packit |
dd8086 |
8 | ( 8 H X
|
|
Packit |
dd8086 |
9 | ) 9 I Y
|
|
Packit |
dd8086 |
a | * : J Z
|
|
Packit |
dd8086 |
b | + ; K
|
|
Packit |
dd8086 |
c | , < L
|
|
Packit |
dd8086 |
d | - = M
|
|
Packit |
dd8086 |
e | . > N
|
|
Packit |
dd8086 |
f | / ? O _
|
|
Packit |
dd8086 |
@end example
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node Glossary
|
|
Packit |
dd8086 |
@appendix Glossary
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@include glossary.texi
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node GNU Free Documentation License
|
|
Packit |
dd8086 |
@appendix GNU Free Documentation License
|
|
Packit |
dd8086 |
@cindex FDL, GNU Free Documentation License
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@include fdl.texi
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@node General Index
|
|
Packit |
dd8086 |
@unnumbered General Index
|
|
Packit |
dd8086 |
@printindex cp
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
@bye
|