BIG REORGANIZATION.

Reorganize directory structure for inclusion of cd-paranoia. Works for
GNU/Linux. Other OS's may be broken. Regression test output needs to
be adjusted too.

Move:
lib/driver (split off of lib)
lib/iso9660 (split off of lib)

Add from paranoia:
lib/cdda_interface
lib/paranoia
src/paranoia

Also made some small changes to capability indentification to show
more reading capabilties and show that.

cd-info now shows the total disc size.
This commit is contained in:
rocky
2004-12-18 17:29:32 +00:00
parent a8f67b6163
commit 6c14d28918
109 changed files with 10863 additions and 329 deletions

View File

@@ -48,6 +48,8 @@ libtool
libcdio.pc
libcdio.spec
libiso9660.pc
libcdio_cdda.pc
libcdio_paranoia.pc
ltmain.sh
mkinstalldirs
stamp-h1

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.29 2004/11/16 00:10:55 nboullis Exp $
# $Id: Makefile.am,v 1.30 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
@@ -29,7 +29,8 @@ SUBDIRS = doc include lib src test example
# pkg-config(1) related rules
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libiso9660.pc libcdio.pc
pkgconfig_DATA = libcdio.pc libcdio_paranoia.pc \
libcdda_interface.pc libiso9660.pc
$(pkgconfig_DATA): config.status

View File

@@ -19,7 +19,7 @@ define(RELEASE_NUM, 72)
define(CDIO_VERSION_STR, 0.$1cvs)
AC_PREREQ(2.52)
AC_REVISION([$Id: configure.ac,v 1.118 2004/12/15 01:45:15 rocky Exp $])dnl
AC_REVISION([$Id: configure.ac,v 1.119 2004/12/18 17:29:32 rocky Exp $])dnl
AC_INIT(libcdio, CDIO_VERSION_STR(RELEASE_NUM))
AC_CONFIG_SRCDIR(src/cd-info.c)
AM_INIT_AUTOMAKE
@@ -123,6 +123,12 @@ dnl headers
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h fcntl.h stdio.h sys/cdio.h glob.h stdbool.h stdarg.h)
AC_CHECK_HEADERS(linux/sbpcd.h, SBPCD_H="-DSBPCD_H='1' ")
AC_CHECK_HEADERS(linux/ucdrom.h, UCDROM_H="-DUCDROM_H='1' ")
AC_SUBST(SBPCD_H)
AC_SUBST(UCDROM_H)
AC_SUBST(TYPESIZES)
dnl compiler
AC_C_BIGENDIAN
@@ -235,11 +241,17 @@ AM_CONDITIONAL(DISABLE_CPP, test "x$disable_cpp" = "xyes")
dnl Checks for header files.
LIBCDIO_CFLAGS='-I$(top_srcdir)/lib/ -I$(top_srcdir)/include/'
LIBCDIO_LIBS='$(top_builddir)/lib/libcdio.la'
LIBISO9660_LIBS='$(top_builddir)/lib/libiso9660.la'
LIBCDIO_CDDA_LIBS='$(top_builddir)/lib/cdda_interface/libcdio_cdda.la'
LIBCDIO_CFLAGS='-I$(top_srcdir)/lib/driver -I$(top_srcdir)/include/'
LIBCDIO_LIBS='$(top_builddir)/lib/driver/libcdio.la'
LIBCDIO_PARANOIA_LIBS='$(top_builddir)/lib/paranoia/libcdio_paranoia.la'
LIBISO9660_CFLAGS='-I$(top_builddir)/lib/iso9660/'
LIBISO9660_LIBS='$(top_builddir)/lib/iso9660/libiso9660.la'
AC_SUBST(LIBCDIO_CDDA_LIBS)
AC_SUBST(LIBCDIO_CFLAGS)
AC_SUBST(LIBISO9660_CFLAGS)
AC_SUBST(LIBCDIO_LIBS)
AC_SUBST(LIBCDIO_PARANOIA_LIBS)
AC_SUBST(LIBISO9660_LIBS)
case $host_os in
@@ -421,7 +433,7 @@ AC_ARG_ENABLE(vcd_info,
enable_vcd_info=yes)
fi
if test x$enable_vcd_info = xyes; then
PKG_CHECK_MODULES(VCDINFO, libvcdinfo >= 0.7.20,
PKG_CHECK_MODULES(VCDINFO, libvcdinfo >= 0.7.21,
[AC_DEFINE([HAVE_VCDINFO],1,
[Define this if you have libvcdinfo installed])],
[AC_MSG_WARN(a new enough libvcdinfo not found.
@@ -439,7 +451,9 @@ AC_CONFIG_COMMANDS([checks],
AC_CONFIG_FILES([ \
Makefile \
libcdio_cdda.pc \
libcdio.pc \
libcdio_paranoia.pc \
libcdio.spec \
libiso9660.pc \
example/Makefile \
@@ -449,6 +463,11 @@ AC_CONFIG_FILES([ \
doc/doxygen/Doxyfile \
doc/Makefile \
lib/Makefile \
lib/cdda_interface/Makefile \
lib/driver/Makefile \
lib/iso9660/Makefile \
lib/paranoia/Makefile \
src/cd-paranoia/Makefile \
src/Makefile \
test/check_nrg.sh \
test/check_cue.sh \

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.14 2004/10/28 10:08:56 rocky Exp $
# $Id: Makefile.am,v 1.15 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
@@ -25,6 +25,8 @@ libcdioincludedir=$(includedir)/cdio
libcdioinclude_HEADERS = \
bytesex.h \
bytesex_asm.h \
paranoia.h \
cdda_interface.h \
cdio.h \
cdtext.h \
cdtext.h \

View File

@@ -0,0 +1,217 @@
/*
$Id: cdda_interface.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Xiph.org
and Heiko Eissfeldt heiko@escape.colossus.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file cdda_paranoia.h
* \brief The top-level interface header; applications include this.
*
******************************************************************/
#ifndef _CDDA_INTERFACE_H_
#define _CDDA_INTERFACE_H_
#include <cdio/paranoia.h>
#define CD_FRAMESAMPLES (CDIO_CD_FRAMESIZE_RAW / 4)
#include <sys/types.h>
#include <signal.h>
/** We keep MAXTRK since this header is exposed publicly and other
programs may have used this.
*/
#define MAXTRK (CDIO_CD_MAX_TRACKS+1)
typedef struct TOC { /* structure of table of contents */
unsigned char bFlags;
unsigned char bTrack;
int32_t dwStartSector;
} TOC;
/** interface types */
#define GENERIC_SCSI 0
#define COOKED_IOCTL 1
#define TEST_INTERFACE 2
#define CDDA_MESSAGE_FORGETIT 0
#define CDDA_MESSAGE_PRINTIT 1
#define CDDA_MESSAGE_LOGIT 2
/** cdrom access function pointer */
struct cdrom_drive_s {
int opened; /* This struct may just represent a candidate for opening */
char *cdda_device_name;
char *ioctl_device_name;
int cdda_fd;
int ioctl_fd;
char *drive_model;
int drive_type;
int interface;
int bigendianp;
int nsectors;
int cd_extra;
int tracks;
TOC disc_toc[MAXTRK];
long audio_first_sector;
long audio_last_sector;
int errordest;
int messagedest;
char *errorbuf;
char *messagebuf;
/* functions specific to particular drives/interrfaces */
int (*enable_cdda) (cdrom_drive_t *d, int onoff);
int (*read_toc) (cdrom_drive_t *d);
long (*read_audio) (cdrom_drive_t *d, void *p, long begin,
long sectors);
int (*set_speed) (cdrom_drive_t *d, int speed);
int error_retry;
int report_all;
int is_atapi;
int is_mmc;
/* SCSI command buffer and offset pointers */
unsigned char *sg;
unsigned char *sg_buffer;
unsigned char inqbytes[4];
/* Scsi parameters and state */
unsigned char density;
unsigned char orgdens;
unsigned int orgsize;
long bigbuff;
int adjust_ssize;
int fua;
int lun;
sigset_t sigset;
};
#define IS_AUDIO(d,i) (!(d->disc_toc[i].bFlags & 0x04))
/** autosense functions */
extern cdrom_drive_t *cdda_find_a_cdrom(int messagedest, char **message);
extern cdrom_drive_t *cdda_identify(const char *device, int messagedest,
char **message);
extern cdrom_drive_t *cdda_identify_cooked(const char *device,int messagedest,
char **message);
extern cdrom_drive_t *cdda_identify_scsi(const char *generic_device,
const char *ioctl_device,
int messagedest, char **message);
#ifdef CDDA_TEST
extern cdrom_drive_t *cdda_identify_test(const char *filename,
int messagedest, char **message);
#endif
/** oriented functions */
extern int cdda_speed_set(cdrom_drive_t *d, int speed);
extern void cdda_verbose_set(cdrom_drive_t *d,int err_action, int mes_action);
extern char *cdda_messages(cdrom_drive_t *d);
extern char *cdda_errors(cdrom_drive_t *d);
extern int cdda_close(cdrom_drive_t *d);
extern int cdda_open(cdrom_drive_t *d);
extern long cdda_read(cdrom_drive_t *d, void *buffer,
long int beginsector, long int sectors);
extern long cdda_track_firstsector(cdrom_drive_t *d,int track);
extern long cdda_track_lastsector(cdrom_drive_t *d,int track);
extern long cdda_tracks(cdrom_drive_t *d);
extern int cdda_sector_gettrack(cdrom_drive_t *d,long sector);
extern int cdda_track_channels(cdrom_drive_t *d,int track);
extern int cdda_track_audiop(cdrom_drive_t *d,int track);
extern int cdda_track_copyp(cdrom_drive_t *d,int track);
extern int cdda_track_preemp(cdrom_drive_t *d,int track);
extern long cdda_disc_firstsector(cdrom_drive_t *d);
extern long cdda_disc_lastsector(cdrom_drive_t *d);
/** transport errors: */
#define TR_OK 0
#define TR_EWRITE 1 /* Error writing packet command (transport) */
#define TR_EREAD 2 /* Error reading packet data (transport) */
#define TR_UNDERRUN 3 /* Read underrun */
#define TR_OVERRUN 4 /* Read overrun */
#define TR_ILLEGAL 5 /* Illegal/rejected request */
#define TR_MEDIUM 6 /* Medium error */
#define TR_BUSY 7 /* Device busy */
#define TR_NOTREADY 8 /* Device not ready */
#define TR_FAULT 9 /* Devive failure */
#define TR_UNKNOWN 10 /* Unspecified error */
#define TR_STREAMING 11 /* loss of streaming */
#ifdef NEED_STRERROR_TR
const char *strerror_tr[]={
"Success",
"Error writing packet command to device",
"Error reading command from device",
"SCSI packet data underrun (too little data)",
"SCSI packet data overrun (too much data)",
"Illegal SCSI request (rejected by target)",
"Medium reading data from medium",
"Device busy",
"Device not ready",
"Target hardware fault",
"Unspecified error",
"Drive lost streaming"
};
#endif /*NEED_STERROR_TR*/
/** Errors returned by lib:
001: Unable to set CDROM to read audio mode
002: Unable to read table of contents lead-out
003: CDROM reporting illegal number of tracks
004: Unable to read table of contents header
005: Unable to read table of contents entry
006: Could not read any data from drive
007: Unknown, unrecoverable error reading data
008: Unable to identify CDROM model
009: CDROM reporting illegal table of contents
010: Unaddressable sector
100: Interface not supported
101: Drive is neither a CDROM nor a WORM device
102: Permision denied on cdrom (ioctl) device
103: Permision denied on cdrom (data) device
300: Kernel memory error
400: Device not open
401: Invalid track number
402: Track not audio data
403: No audio tracks on disc
*/
#endif /*_CDDA_INTERFACE_H_*/

View File

@@ -1,5 +1,5 @@
/* -*- c -*-
$Id: cdio.h,v 1.67 2004/12/15 01:45:15 rocky Exp $
$Id: cdio.h,v 1.68 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -469,65 +469,65 @@ extern "C" {
unsigned int i_sectors);
/*!
Reads a mode1 sector
Reads a mode 1 sector
@param p_cdio object to read from
@param buf place to read data into
@param lsn sector to read
@param b_form2 true for reading mode1 form2 sectors or false for
mode1 form1 sectors.
@param b_form2 true for reading mode1 form 2 sectors or false for
mode 1 form 1 sectors.
@return 0 if no error, nonzero otherwise.
*/
int cdio_read_mode1_sector (const CdIo *p_cdio, void *buf, lsn_t lsn,
int cdio_read_mode1_sector (const CdIo *p_cdio, void *p_buf, lsn_t i_lsn,
bool b_form2);
/*!
Reads mode1 sectors
Reads mode 1 sectors
@param p_cdio object to read from
@param buf place to read data into
@param lsn sector to read
@param b_form2 true for reading mode1 form2 sectors or false for
mode1 form1 sectors.
@param b_form2 true for reading mode 1 form 2 sectors or false for
mode 1 form 1 sectors.
@param i_sectors number of sectors to read
@return 0 if no error, nonzero otherwise.
*/
int cdio_read_mode1_sectors (const CdIo *p_cdio, void *buf, lsn_t lsn,
int cdio_read_mode1_sectors (const CdIo *p_cdio, void *p_buf, lsn_t i_lsn,
bool b_form2, unsigned int i_sectors);
/*!
Reads a mode1 sector
Reads a mode 2 sector
@param p_cdio object to read from
@param buf place to read data into
@param lsn sector to read
@param b_form2 true for reading mode1 form2 sectors or false for
mode1 form1 sectors.
@param b_form2 true for reading mode 2 form 2 sectors or false for
mode 2 form 1 sectors.
@return 0 if no error, nonzero otherwise.
*/
int cdio_read_mode2_sector (const CdIo *p_cdio, void *buf, lsn_t lsn,
int cdio_read_mode2_sector (const CdIo *p_cdio, void *p_buf, lsn_t i_lsn,
bool b_form2);
/*!
Reads mode2 sectors
Reads mode 2 sectors
@param p_cdio object to read from
@param buf place to read data into
@param lsn sector to read
@param b_form2 true for reading mode1 form2 sectors or false for
mode1 form1 sectors.
@param b_form2 true for reading mode2 form 2 sectors or false for
mode 2 form 1 sectors.
@param i_sectors number of sectors to read
@return 0 if no error, nonzero otherwise.
*/
int cdio_read_mode2_sectors (const CdIo *p_cdio, void *buf, lsn_t lsn,
int cdio_read_mode2_sectors (const CdIo *p_cdio, void *p_buf, lsn_t i_lsn,
bool b_form2, unsigned int i_sectors);
/*!
Set the arg "key" with "value" in "obj".
Set the arg "key" with "value" in "p_cdio".
@param p_cdio the CD object to set
@param key the key to set

123
include/cdio/paranoia.h Normal file
View File

@@ -0,0 +1,123 @@
/*
$Id: paranoia.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file cdda_paranoia.h
* \brief The top-level header for libcdda_paranoia:
a library for reading CD-DA with error tolerance and repair.
*/
#ifndef _CDIO_PARANOIA_H_
#define _CDIO_PARANOIA_H_
#include <cdio/cdio.h>
#define CD_FRAMEWORDS (CDIO_CD_FRAMESIZE_RAW/2)
/**! Flags used in paranoia_modeset. */
#define PARANOIA_MODE_FULL 0xff
#define PARANOIA_MODE_DISABLE 0
#define PARANOIA_MODE_VERIFY 1
#define PARANOIA_MODE_FRAGMENT 2
#define PARANOIA_MODE_OVERLAP 4
#define PARANOIA_MODE_SCRATCH 8
#define PARANOIA_MODE_REPAIR 16
#define PARANOIA_MODE_NEVERSKIP 32
/** cdrom_paranoia is an opaque structure which is used in all of the
library operations.
*/
typedef struct cdrom_paranoia_s cdrom_paranoia_t;
typedef struct cdrom_drive_s cdrom_drive_t;
typedef enum {
PARANOIA_CB_READ,
PARANOIA_CB_VERIFY,
PARANOIA_CB_FIXUP_EDGE,
PARANOIA_CB_FIXUP_ATOM,
PARANOIA_CB_SCRATCH,
PARANOIA_CB_REPAIR,
PARANOIA_CB_SKIP,
PARANOIA_CB_DRIFT,
PARANOIA_CB_BACKOFF,
PARANOIA_CB_OVERLAP,
PARANOIA_CB_FIXUP_DROPPED,
PARANOIA_CB_FIXUP_DUPED,
PARANOIA_CB_READERR
} paranoia_cb_mode_t;
#ifdef __cplusplus
extern "C" {
#endif
/*!
Get and initialize a new cdrom_paranoia object from cdrom_drive.
Run this before calling any of the other paranoia routines below.
@return new cdrom_paranoia object Call paranoia_free() when you are
done with it
*/
extern cdrom_paranoia_t *paranoia_init(cdrom_drive_t *d);
/*!
Free any resources associated with obj.
@see paranoia_init.
*/
extern void paranoia_free(cdrom_paranoia_t *p);
/*!
Set the kind of repair you want to on for reading.
The modes are listed above
*/
extern void paranoia_modeset(cdrom_paranoia_t *p, int mode);
/*!
reposition reading offset.
@param whence like corresponding parameter in libc's lseek, e.g.
SEEK_SET or SEEK_END.
*/
extern lsn_t paranoia_seek(cdrom_paranoia_t *p, off_t seek, int whence);
/*! The returned buffer is *not* to be freed by the caller. It will
persist only until the next call to paranoia_read() for this p
*/
extern int16_t *paranoia_read(cdrom_paranoia_t *p,
void(*callback)(long int, paranoia_cb_mode_t));
extern int16_t *paranoia_read_limited(cdrom_paranoia_t *p,
void(*callback)(long int,
paranoia_cb_mode_t),
int maxretries);
extern void paranoia_overlapset(cdrom_paranoia_t *p,long overlap);
extern void paranoia_set_range(cdrom_paranoia_t *p, long int start,
long int end);
#ifdef __cplusplus
}
#endif
#endif /*_CDIO_PARANOIA_H_*/

View File

@@ -1,5 +1,5 @@
/*
$Id: scsi_mmc.h,v 1.35 2004/12/04 12:01:48 rocky Exp $
$Id: scsi_mmc.h,v 1.36 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -415,12 +415,18 @@ char *scsi_mmc_get_mcn ( const CdIo *p_cdio );
Can read only up to 25 blocks.
*/
int scsi_mmc_read_sectors ( const CdIo *p_cdio, void *p_buf, lba_t lba,
int sector_type, unsigned int nblocks);
int sector_type, unsigned int i_blocks);
/*!
Set the block size for subsequest read requests, via a SCSI MMC
MODE_SELECT 6 command.
*/
int scsi_mmc_set_blocksize ( const CdIo *p_cdio, unsigned int bsize);
int scsi_mmc_set_blocksize ( const CdIo *p_cdio, unsigned int i_bsize);
/*!
Set the block size for subsequest read requests, via a SCSI MMC
MODE_SENSE 6 command.
*/
int scsi_mmc_get_blocksize ( const CdIo *p_cdio );
#endif /* __SCSI_MMC_H__ */

View File

@@ -1,5 +1,5 @@
/*
$Id: types.h,v 1.23 2004/09/03 23:20:11 rocky Exp $
$Id: types.h,v 1.24 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -298,8 +298,6 @@ extern "C" {
#define CDIO_DRIVE_CAP_MISC_MULTI_SESSION 0x00020 /**< read sessions>1 */
#define CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED 0x00080 /**< media changed */
#define CDIO_DRIVE_CAP_MISC_RESET 0x00100 /**< hard reset device */
#define CDIO_DRIVE_CAP_MCN 0x00200 /**< can read MCN */
#define CDIO_DRIVE_CAP_ISRC 0x00200 /**< can read ISRC */
#define CDIO_DRIVE_CAP_MISC_FILE 0x20000 /**< drive is really a file,
i.e a CD file image */
@@ -316,6 +314,10 @@ extern "C" {
#define CDIO_DRIVE_CAP_READ_DVD_RW 0x00200 /**< drive can read DVD-RW */
#define CDIO_DRIVE_CAP_READ_DVD_RPW 0x00400 /**< drive can read DVD+RW */
#define CDIO_DRIVE_CAP_READ_C2_ERRS 0x00800 /**< has C2 error correction */
#define CDIO_DRIVE_CAP_READ_MODE2_FORM1 0x01000 /**< can read mode 2 form 1 */
#define CDIO_DRIVE_CAP_READ_MODE2_FORM2 0x02000 /**< can read mode 2 form 2 */
#define CDIO_DRIVE_CAP_READ_MCN 0x04000 /**< can read MCN */
#define CDIO_DRIVE_CAP_READ_ISRC 0x08000 /**< can read ISRC */
/*! Writing masks.. */
#define CDIO_DRIVE_CAP_WRITE_CD_R 0x00001 /**< drive can write CD-R */

View File

@@ -1,9 +1,3 @@
.deps
.libs
Makefile
Makefile.in
*.o
*.lo
*.la
*.la.ver

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.64 2004/12/15 01:45:15 rocky Exp $
# $Id: Makefile.am,v 1.65 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
@@ -17,187 +17,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
########################################################
# Things to make the libcdio and libiso9660 libraries
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libcdio_la_CURRENT := 3
libcdio_la_REVISION := 0
libcdio_la_AGE := 0
libiso9660_la_CURRENT := 3
libiso9660_la_REVISION := 0
libiso9660_la_AGE := 0
EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \
libcdio.sym libiso9660.sym
noinst_HEADERS = cdio_assert.h cdio_private.h portable.h
libcdio_sources = \
_cdio_aix.c \
_cdio_bsdi.c \
_cdio_generic.c \
_cdio_linux.c \
_cdio_osx.c \
_cdio_stdio.c \
_cdio_stdio.h \
_cdio_stream.c \
_cdio_stream.h \
_cdio_sunos.c \
cd_types.c \
cdio.c \
cdtext.c \
cdtext_private.h \
ds.c \
FreeBSD/freebsd.c \
FreeBSD/freebsd.h \
FreeBSD/freebsd_cam.c \
FreeBSD/freebsd_ioctl.c \
generic.h \
image.h \
image/bincue.c \
image/cdrdao.c \
image_common.h \
image/nrg.c \
image/nrg.h \
MSWindows/aspi32.c \
MSWindows/aspi32.h \
MSWindows/win32_ioctl.c \
MSWindows/win32.c \
MSWindows/win32.h \
logging.c \
scsi_mmc.c \
scsi_mmc_private.h \
sector.c \
util.c
lib_LTLIBRARIES = libcdio.la libiso9660.la
libcdio_la_SOURCES = $(libcdio_sources)
libcdio_la_ldflags = -version-info $(libcdio_la_CURRENT):$(libcdio_la_REVISION):$(libcdio_la_AGE)
libiso9660_la_SOURCES = \
iso9660.c \
iso9660_private.h \
iso9660_fs.c \
xa.c
libiso9660_la_LIBADD = libcdio.la
libiso9660_la_ldflags = -version-info $(libiso9660_la_CURRENT):$(libiso9660_la_REVISION):$(libiso9660_la_AGE)
INCLUDES = $(LIBCDIO_CFLAGS)
########################################################
# Things to version the symbols in the libraries
# make all libraries
########################################################
# An explanation of the versioning problem from Nicolas Boullis and
# the versioned symbol solution he uses below...
#
# Currently, libvcdinfo uses the cdio_open function from libcdio.
# Let's imagine a program foobar that uses both the vcdinfo_open
# function from libvcdinfo and the cdio_open function from libcdio.
# Currently, libcdio has SONAME libcdio.so.0, libvcdinfo has SONAME
# libvcdinfo.so.0 and requires libcdio.so.0, and foobar requires both
# libvcdinfo.so.0 and libcdio.so.0. Everything looks fine.
#
# Now, for some reason, you decide to change the cdio_open function.
# That's your right, but you have to bump the CURRENT version and (if I
# understand it correctly, athough this is not that clear in libtool's
# documentation) set the AGE to 0. Anyway, this bumps the SONAME, which is
# sane since the interface changes incompatibly.
# Now, you have a new libcdio with SONAME libcdio.so.1. But libvcdinfo and
# foobar still require libcdio.so.0. Everything is still fine.
# Now, after some minor changes, the author of foobar recompiles foobar.
# Then, foobar now requires libvcdinfo.so.0 and libcdio.so.1. And foobar
# now segfaults...
# What is happening? When you run foobar, if brings both libvcdinfo.so.0
# and libcdio.so.1, but libvcdinfo.so.0 also brings libcdio.so.0. So you
# have both libcdio.so.0 and libcdio.so.1 that bring their symbols to the
# global namespace. Hence, you have to incompatible versions of the
# cdio_open function in the name space. When foobar calls cdio_open, it
# may choose the wrong function, and segfaults...
# With versioned symbols, the cdio_open function from libcdio.so.0 may be
# known as (something that looks like) cdio_open@@CDIO_0. An the cdio_open
# function from libcdio.so.1 as cdio_open@@CDIO_1. Both versions of
# libcdio would still be brought in by the most recent foobar, but foobar
# (and libvcdinfo) know which versioned function to use and then use the
# good one.
# This is some simple versioning where every symbol is versioned with
# something that looks like the SONAME of the library. More complex (and
# better) versioning is possible; it is for example what is used by glibc.
# But good complex versioning is something that requires much more
# work...
# The below is a impliments symbol versioning. First of all, I
# compute MAJOR as CURENT - AGE; that is what is used within libtool
# (at least on GNU/Linux systems) for the number in the SONAME. The
# nm command gives the list of symbols known in each of the object
# files that will be part of the shared library. And the sed command
# extracts from this list those symbols that will be shared. (This sed
# command comes from libtool.)
libcdio_la_MAJOR := $(shell expr $(libcdio_la_CURRENT) - $(libcdio_la_AGE))
if BUILD_VERSIONED_LIBS
libcdio_la_LDFLAGS = $(libcdio_la_ldflags) -Wl,--version-script=libcdio.la.ver
libcdio_la_DEPENDENCIES = libcdio.la.ver
libcdio.la.ver: $(libcdio_la_OBJECTS) $(srcdir)/libcdio.sym
echo 'CDIO_$(libcdio_la_MAJOR) { ' > $@
echo " global:" >> $@
nm $(patsubst %.lo,%.o,$(libcdio_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libcdio.sym; then echo " $${symbol};"; fi; done >> $@
echo " local:" >> $@
nm $(patsubst %.lo,%.o,$(libcdio_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libcdio.sym; then :; else echo " $${symbol};"; fi; done >> $@
echo '};' >> $@
else
libcdio_la_LDFLAGS = $(libcdio_la_ldflags)
endif
libiso9660_la_MAJOR := $(shell expr $(libiso9660_la_CURRENT) - $(libiso9660_la_AGE))
if BUILD_VERSIONED_LIBS
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags) -Wl,--version-script=libiso9660.la.ver
libiso9660_la_DEPENDENCIES = libcdio.la libiso9660.la.ver
libiso9660.la.ver: $(libiso9660_la_OBJECTS) $(srcdir)/libiso9660.sym
echo 'ISO9660_$(libiso9660_la_MAJOR) {' > $@
echo " global:" >> $@
nm $(patsubst %.lo,%.o,$(libiso9660_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then echo " $${symbol};"; fi; done >> $@
echo " local:" >> $@
nm $(patsubst %.lo,%.o,$(libiso9660_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then :; else echo " $${symbol};"; fi; done >> $@
echo '};' >> $@
MOSTLYCLEANFILES = libcdio.la.ver libiso9660.la.ver
else
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags)
libiso9660_la_DEPENDENCIES = libcdio.la
endif
SUBDIRS = driver iso9660 cdda_interface paranoia

View File

@@ -0,0 +1,8 @@
.deps
.libs
Makefile
Makefile.in
*.o
*.lo
*.la
*.la.ver

View File

@@ -0,0 +1,76 @@
# $Id: Makefile.am,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
########################################################
# Things to make the cdda_interface library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libcdio_cdda_la_CURRENT := 0
libcdio_cdda_la_REVISION := 0
libcdio_cdda_la_AGE := 0
noinst_HEADERS = common_interface.h drive_exceptions.h low_interface.h \
smallft.h utils.h
libcdio_cdda_sources = common_interface.c cooked_interface.c interface.c \
scan_devices.c scsi_interface.c smallft.c test_interface.c \
toc.c utils.c
lib_LTLIBRARIES = libcdio_cdda.la
libcdio_cdda_la_SOURCES = $(libcdio_cdda_sources)
libcdio_cdda_la_ldflags = -version-info $(libcdio_cdda_la_CURRENT):$(libcdio_cdda_la_REVISION):$(libcdio_cdda_la_AGE)
libcdio_cdda_la_LDFLAGS = $(libcdio_cdda_la_ldflags)
INCLUDES = $(LIBCDIO_CFLAGS)
FLAGS=@LIBCDIO_CFLAGS@ @UCDROM_H@ @TYPESIZES@ @CFLAGS@
OPT=$(FLAGS)
DEBUG=$(FLAGS) -DCDDA_TEST
## test:
## $(MAKE) libcdio_cdda.a CFLAGS="$(DEBUG)"
## $(CC) $(DEBUG) -c test_interface.c
## $(LD) $(DEBUG) test_interface.o $(LDFLAGS) -o cdda_test $(LIBS) libcdio_cdda.a
LIBS = $(LIBCDIO_LIBS)

View File

@@ -0,0 +1,262 @@
/*
$Id: common_interface.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998, 2002 Monty monty@xiph.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
*
* CDROM communication common to all interface methods is done here
* (mostly ioctl stuff, but not ioctls specific to the 'cooked'
* interface)
*
******************************************************************/
#include <math.h>
#include "common_interface.h"
#include "utils.h"
#include "smallft.h"
#include <linux/hdreg.h>
/* Test for presence of a cdrom by pinging with the 'CDROMVOLREAD' ioctl() */
int
ioctl_ping_cdrom(int fd)
{
struct cdrom_volctrl volctl;
if (ioctl(fd, CDROMVOLREAD, &volctl))
return(1); /* failure */
return(0);
/* success! */
}
/* Use the ioctl thingy above ping the cdrom; this will get model info */
char *atapi_drive_info(int fd){
/* Work around the fact that the struct grew without warning in
2.1/2.0.34 */
struct hd_driveid *id=malloc(512); /* the size in 2.0.34 */
char *ret;
if (!(ioctl(fd, HDIO_GET_IDENTITY, id))) {
if(id->model==0 || id->model[0]==0)
ret=copystring("Generic Unidentifiable ATAPI CDROM");
else
ret=copystring(id->model);
}else
ret=copystring("Generic Unidentifiable CDROM");
free(id);
return(ret);
}
int
data_bigendianp(cdrom_drive_t *d)
{
float lsb_votes=0;
float msb_votes=0;
int i,checked;
int endiancache=d->bigendianp;
float *a=calloc(1024,sizeof(float));
float *b=calloc(1024,sizeof(float));
long readsectors=5;
int16_t *buff=malloc(readsectors*CDIO_CD_FRAMESIZE_RAW);
/* look at the starts of the audio tracks */
/* if real silence, tool in until some static is found */
/* Force no swap for now */
d->bigendianp=-1;
cdmessage(d,"\nAttempting to determine drive endianness from data...");
d->enable_cdda(d,1);
for(i=0,checked=0;i<d->tracks;i++){
float lsb_energy=0;
float msb_energy=0;
if(cdda_track_audiop(d,i+1)==1){
long firstsector=cdda_track_firstsector(d,i+1);
long lastsector=cdda_track_lastsector(d,i+1);
int zeroflag=-1;
long beginsec=0;
/* find a block with nonzero data */
while(firstsector+readsectors<=lastsector){
int j;
if(d->read_audio(d,buff,firstsector,readsectors)>0){
/* Avoid scanning through jitter at the edges */
for(beginsec=0;beginsec<readsectors;beginsec++){
int offset=beginsec*CDIO_CD_FRAMESIZE_RAW/2;
/* Search *half* */
for(j=460;j<128+460;j++)
if(buff[offset+j]!=0){
zeroflag=0;
break;
}
if(!zeroflag)break;
}
if(!zeroflag)break;
firstsector+=readsectors;
}else{
d->enable_cdda(d,0);
free(a);
free(b);
free(buff);
return(-1);
}
}
beginsec*=CDIO_CD_FRAMESIZE_RAW/2;
/* un-interleave for an fft */
if(!zeroflag){
int j;
for(j=0;j<128;j++)a[j]=le16_to_cpu(buff[j*2+beginsec+460]);
for(j=0;j<128;j++)b[j]=le16_to_cpu(buff[j*2+beginsec+461]);
fft_forward(128,a,NULL,NULL);
fft_forward(128,b,NULL,NULL);
for(j=0;j<128;j++)lsb_energy+=fabs(a[j])+fabs(b[j]);
for(j=0;j<128;j++)a[j]=be16_to_cpu(buff[j*2+beginsec+460]);
for(j=0;j<128;j++)b[j]=be16_to_cpu(buff[j*2+beginsec+461]);
fft_forward(128,a,NULL,NULL);
fft_forward(128,b,NULL,NULL);
for(j=0;j<128;j++)msb_energy+=fabs(a[j])+fabs(b[j]);
}
}
if(lsb_energy<msb_energy){
lsb_votes+=msb_energy/lsb_energy;
checked++;
}else
if(lsb_energy>msb_energy){
msb_votes+=lsb_energy/msb_energy;
checked++;
}
if(checked==5 && (lsb_votes==0 || msb_votes==0))break;
cdmessage(d,".");
}
free(buff);
free(a);
free(b);
d->bigendianp=endiancache;
d->enable_cdda(d,0);
/* How did we vote? Be potentially noisy */
if(lsb_votes>msb_votes){
char buffer[256];
cdmessage(d,"\n\tData appears to be coming back little endian.\n");
sprintf(buffer,"\tcertainty: %d%%\n",(int)
(100.*lsb_votes/(lsb_votes+msb_votes)+.5));
cdmessage(d,buffer);
return(0);
}else{
if(msb_votes>lsb_votes){
char buffer[256];
cdmessage(d,"\n\tData appears to be coming back big endian.\n");
sprintf(buffer,"\tcertainty: %d%%\n",(int)
(100.*msb_votes/(lsb_votes+msb_votes)+.5));
cdmessage(d,buffer);
return(1);
}
cdmessage(d,"\n\tCannot determine CDROM drive endianness.\n");
return(bigendianp());
return(-1);
}
}
/************************************************************************/
/* Here we fix up a couple of things that will never happen. yeah,
right. The multisession stuff is from Hannu's code; it assumes it
knows the leadoud/leadin size. */
int
FixupTOC(cdrom_drive_t *d,int tracks)
{
struct cdrom_multisession ms_str;
int j;
/* First off, make sure the 'starting sector' is >=0 */
for(j=0;j<tracks;j++){
if(d->disc_toc[j].dwStartSector<0){
cdmessage(d,"\n\tTOC entry claims a negative start offset: massaging"
".\n");
d->disc_toc[j].dwStartSector=0;
}
if(j<tracks-1 && d->disc_toc[j].dwStartSector>
d->disc_toc[j+1].dwStartSector){
cdmessage(d,"\n\tTOC entry claims an overly large start offset: massaging"
".\n");
d->disc_toc[j].dwStartSector=0;
}
}
/* Make sure the listed 'starting sectors' are actually increasing.
Flag things that are blatant/stupid/wrong */
{
long last=d->disc_toc[0].dwStartSector;
for(j=1;j<tracks;j++){
if(d->disc_toc[j].dwStartSector<last){
cdmessage(d,"\n\tTOC entries claim non-increasing offsets: massaging"
".\n");
d->disc_toc[j].dwStartSector=last;
}
last=d->disc_toc[j].dwStartSector;
}
}
/* For a scsi device, the ioctl must go to the specialized SCSI
CDROM device, not the generic device. */
if (d->ioctl_fd != -1) {
int result;
ms_str.addr_format = CDROM_LBA;
result = ioctl(d->ioctl_fd, CDROMMULTISESSION, &ms_str);
if (result == -1) return -1;
if (ms_str.addr.lba > 100) {
/* This is an odd little piece of code --Monty */
/* believe the multisession offset :-) */
/* adjust end of last audio track to be in the first session */
for (j = tracks-1; j >= 0; j--) {
if (j > 0 && !IS_AUDIO(d,j) && IS_AUDIO(d,j-1)) {
if ((d->disc_toc[j].dwStartSector > ms_str.addr.lba - 11400) &&
(ms_str.addr.lba - 11400 > d->disc_toc[j-1].dwStartSector))
d->disc_toc[j].dwStartSector = ms_str.addr.lba - 11400;
break;
}
}
return 1;
}
}
return 0;
}

View File

@@ -0,0 +1,34 @@
/*
$Id: common_interface.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CDDA_COMMON_INTERFACE_H_
#define _CDDA_COMMON_INTERFACE_H_
#include "low_interface.h"
/* Test for presence of a cdrom by pinging with the 'CDROMVOLREAD' ioctl() */
extern int ioctl_ping_cdrom(int fd);
extern char *atapi_drive_info(int fd);
extern int data_bigendianp(cdrom_drive_t *d);
extern int FixupTOC(cdrom_drive_t *d,int tracks);
#endif /*_CDDA_COMMON_INTERFACE_H_*/

View File

@@ -0,0 +1,291 @@
/*
$Id: cooked_interface.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Original interface.c Copyright (C) 1994-1997
Eissfeldt heiko@colossus.escape.de
Current blenderization Copyright (C) 1998-1999 Monty xiphmont@mit.edu
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
*
* CDROM code specific to the cooked ioctl interface
*
******************************************************************/
#include "low_interface.h"
#include "common_interface.h"
#include "utils.h"
static int
cooked_readtoc (cdrom_drive_t *d)
{
int i;
int tracks;
struct cdrom_tochdr hdr;
struct cdrom_tocentry entry;
/* get TocHeader to find out how many entries there are */
if(ioctl(d->ioctl_fd, CDROMREADTOCHDR, &hdr ))
switch(errno){
case EPERM:
cderror(d,"102: Permision denied on cdrom (ioctl) device\n");
return(-102);
default:
cderror(d,"004: Unable to read table of contents header\n");
return(-4);
}
/* get all TocEntries */
for(i=0;i<hdr.cdth_trk1;i++){
entry.cdte_track= i+1;
entry.cdte_format = CDROM_LBA;
if(ioctl(d->ioctl_fd,CDROMREADTOCENTRY,&entry)){
cderror(d,"005: Unable to read table of contents entry\n");
return(-5);
}
d->disc_toc[i].bFlags = (entry.cdte_adr << 4) | (entry.cdte_ctrl & 0x0f);
d->disc_toc[i].bTrack = i+1;
d->disc_toc[i].dwStartSector = entry.cdte_addr.lba;
}
entry.cdte_track = CDIO_CDROM_LEADOUT_TRACK;
entry.cdte_format = CDROM_LBA;
if(ioctl(d->ioctl_fd, CDROMREADTOCENTRY, &entry)){
cderror(d,"005: Unable to read table of contents entry\n");
return(-5);
}
d->disc_toc[i].bFlags = (entry.cdte_adr << 4) | (entry.cdte_ctrl & 0x0f);
d->disc_toc[i].bTrack = entry.cdte_track;
d->disc_toc[i].dwStartSector = entry.cdte_addr.lba;
tracks=hdr.cdth_trk1+1;
d->cd_extra=FixupTOC(d,tracks);
return(--tracks); /* without lead-out */
}
/* Set operating speed */
static int
cooked_setspeed(cdrom_drive_t *d, int speed)
{
if(d->ioctl_fd!=-1)
return ioctl(d->ioctl_fd, CDROM_SELECT_SPEED, speed);
else
return 0;
}
/* read 'SectorBurst' adjacent sectors of audio sectors
* to Buffer '*p' beginning at sector 'lSector'
*/
static long int
cooked_read (cdrom_drive_t *d, void *p, long begin, long sectors)
{
int retry_count,err;
struct cdrom_read_audio arg;
char *buffer=(char *)p;
/* read d->nsectors at a time, max. */
sectors=(sectors>d->nsectors?d->nsectors:sectors);
arg.addr.lba = begin;
arg.addr_format = CDROM_LBA;
arg.nframes = sectors;
arg.buf=buffer;
retry_count=0;
do {
if((err=ioctl(d->ioctl_fd, CDROMREADAUDIO, &arg))){
if(!d->error_retry)return(-7);
switch(errno){
case ENOMEM:
/* D'oh. Possible kernel error. Keep limping */
if(sectors==1){
/* Nope, can't continue */
cderror(d,"300: Kernel memory error\n");
return(-300);
}
default:
if(sectors==1){
/* *Could* be I/O or media error. I think. If we're at
30 retries, we better skip this unhappy little
sector. */
if(retry_count>MAX_RETRIES-1){
char b[256];
sprintf(b,"010: Unable to access sector %ld: skipping...\n",
begin);
cderror(d,b);
return(-10);
}
break;
}
}
if(retry_count>4)
if(sectors>1)
sectors=sectors*3/4;
retry_count++;
if(retry_count>MAX_RETRIES){
cderror(d,"007: Unknown, unrecoverable error reading data\n");
return(-7);
}
}else
break;
} while (err);
return(sectors);
}
/* hook */
static int Dummy (cdrom_drive_t *d,int Switch)
{
return(0);
}
static int
verify_read_command(cdrom_drive_t *d)
{
int i;
int16_t *buff=malloc(CD_FRAMESIZE_RAW);
int audioflag=0;
cdmessage(d,"Verifying drive can read CDDA...\n");
d->enable_cdda(d,1);
for(i=1;i<=d->tracks;i++){
if(cdda_track_audiop(d,i)==1){
long firstsector=cdda_track_firstsector(d,i);
long lastsector=cdda_track_lastsector(d,i);
long sector=(firstsector+lastsector)>>1;
audioflag=1;
if(d->read_audio(d,buff,sector,1)>0){
cdmessage(d,"\tExpected command set reads OK.\n");
d->enable_cdda(d,0);
free(buff);
return(0);
}
}
}
d->enable_cdda(d,0);
if(!audioflag){
cdmessage(d,"\tCould not find any audio tracks on this disk.\n");
return(-403);
}
cdmessage(d,"\n\tUnable to read any data; "
"drive probably not CDDA capable.\n");
cderror(d,"006: Could not read any data from drive\n");
free(buff);
return(-6);
}
#include "drive_exceptions.h"
static void
check_exceptions(cdrom_drive_t *d, const exception_t *list)
{
int i=0;
while(list[i].model){
if(!strncmp(list[i].model,d->drive_model,strlen(list[i].model))){
if(list[i].bigendianp!=-1)d->bigendianp=list[i].bigendianp;
return;
}
i++;
}
}
/* set function pointers to use the ioctl routines */
int
cooked_init_drive (cdrom_drive_t *d){
int ret;
switch(d->drive_type){
case MATSUSHITA_CDROM_MAJOR: /* sbpcd 1 */
case MATSUSHITA_CDROM2_MAJOR: /* sbpcd 2 */
case MATSUSHITA_CDROM3_MAJOR: /* sbpcd 3 */
case MATSUSHITA_CDROM4_MAJOR: /* sbpcd 4 */
/* don't make the buffer too big; this sucker don't preempt */
cdmessage(d,"Attempting to set sbpcd buffer size...\n");
d->nsectors=8;
while(1){
/* this ioctl returns zero on error; exactly wrong, but that's
what it does. */
if(ioctl(d->ioctl_fd, CDROMAUDIOBUFSIZ, d->nsectors)==0){
d->nsectors>>=1;
if(d->nsectors==0){
char buffer[256];
d->nsectors=8;
sprintf(buffer,"\tTrouble setting buffer size. Defaulting to %d sectors.\n",
d->nsectors);
cdmessage(d,buffer);
break; /* Oh, well. Try to read anyway.*/
}
}else{
char buffer[256];
sprintf(buffer,"\tSetting read block size at %d sectors (%ld bytes).\n",
d->nsectors,(long)d->nsectors*CD_FRAMESIZE_RAW);
cdmessage(d,buffer);
break;
}
}
break;
case IDE0_MAJOR:
case IDE1_MAJOR:
case IDE2_MAJOR:
case IDE3_MAJOR:
d->nsectors=8; /* it's a define in the linux kernel; we have no
way of determining other than this guess tho */
d->bigendianp=0;
d->is_atapi=1;
check_exceptions(d, atapi_list);
break;
default:
d->nsectors=40;
}
d->enable_cdda = Dummy;
d->read_audio = cooked_read;
d->set_speed = cooked_setspeed;
d->read_toc = cooked_readtoc;
ret=d->tracks=d->read_toc(d);
if(d->tracks<1)
return(ret);
d->opened=1;
if((ret=verify_read_command(d)))return(ret);
d->error_retry=1;
return(0);
}

View File

@@ -0,0 +1,95 @@
/*
$Id: drive_exceptions.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
extern int scsi_enable_cdda(cdrom_drive_t *d, int);
extern long scsi_read_mmc(cdrom_drive_t *d, void *,long,long);
extern long scsi_read_mmc2(cdrom_drive_t *d, void *,long,long);
extern long scsi_read_D4_10(cdrom_drive_t *, void *,long,long);
extern long scsi_read_D4_12(cdrom_drive_t *, void *,long,long);
extern long scsi_read_D8(cdrom_drive_t *, void *,long,long);
extern long scsi_read_28(cdrom_drive_t *, void *,long,long);
extern long scsi_read_A8(cdrom_drive_t *, void *,long,long);
typedef struct exception {
const char *model;
int atapi; /* If the ioctl doesn't work */
unsigned char density;
int (*enable)(cdrom_drive_t *,int);
long (*read)(cdrom_drive_t *,void *, long, long);
int bigendianp;
} exception_t;
/* specific to general */
/* list of drives that affect autosensing in ATAPI specific portions of code
(force drives to detect as ATAPI or SCSI, force ATAPI read command */
static exception_t atapi_list[]={
{"SAMSUNG SCR-830 REV 2.09 2.09 ", 1, 0, Dummy,scsi_read_mmc2,0},
{"Memorex CR-622", 1, 0, Dummy, NULL,0},
{"SONY CD-ROM CDU-561", 0, 0, Dummy, NULL,0},
{"Chinon CD-ROM CDS-525", 0, 0, Dummy, NULL,0},
{NULL,0,0,NULL,NULL,0}};
/* list of drives that affect MMC default settings */
#ifdef NEED_MMC_LIST
static exception_t mmc_list[]={
{"SAMSUNG SCR-830 REV 2.09 2.09 ", 1, 0, Dummy,scsi_read_mmc2,0},
{"Memorex CR-622", 1, 0, Dummy, NULL,0},
{"SONY CD-ROM CDU-561", 0, 0, Dummy, NULL,0},
{"Chinon CD-ROM CDS-525", 0, 0, Dummy, NULL,0},
{"KENWOOD CD-ROM UCR", -1, 0, NULL,scsi_read_D8, 0},
{NULL,0,0,NULL,NULL,0}};
#endif /*NEED_MMC_LIST*/
/* list of drives that affect SCSI default settings */
#ifdef NEED_SCSI_LIST
static exception_t scsi_list[]={
{"TOSHIBA", -1,0x82,scsi_enable_cdda,scsi_read_28, 0},
{"IBM", -1,0x82,scsi_enable_cdda,scsi_read_28, 0},
{"DEC", -1,0x82,scsi_enable_cdda,scsi_read_28, 0},
{"IMS", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"KODAK", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"RICOH", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"HP", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"PHILIPS", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"PLASMON", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"GRUNDIG CDR100IPW", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"MITSUMI CD-R ", -1, 0,scsi_enable_cdda,scsi_read_28, 1},
{"KENWOOD CD-ROM UCR", -1, 0, NULL,scsi_read_D8, 0},
{"YAMAHA", -1, 0,scsi_enable_cdda, NULL, 0},
{"PLEXTOR", -1, 0, NULL, NULL, 0},
{"SONY", -1, 0, NULL, NULL, 0},
{"NEC", -1, 0, NULL,scsi_read_D4_10,0},
/* the 7501 locks up if hit with the 10 byte version from the
autoprobe first */
{"MATSHITA CD-R CW-7501", -1, 0, NULL,scsi_read_D4_12,-1},
{NULL,0,0,NULL,NULL,0}};
#endif /* NEED_SCSI_LIST*/

View File

@@ -0,0 +1,149 @@
/******************************************************************
* CopyPolicy: GNU Public License 2 applies
* Copyright (C) 1998 Monty xiphmont@mit.edu
*
* Top-level interface module for cdrom drive access. SCSI, ATAPI, etc
* specific stuff are in other modules. Note that SCSI does use
* specialized ioctls; these appear in common_interface.c where the
* generic_scsi stuff is in scsi_interface.c.
*
******************************************************************/
#include "low_interface.h"
#include "common_interface.h"
#include "utils.h"
static void _clean_messages(cdrom_drive_t *d)
{
if(d){
if(d->messagebuf)free(d->messagebuf);
if(d->errorbuf)free(d->errorbuf);
d->messagebuf=NULL;
d->errorbuf=NULL;
}
}
/* doubles as "cdrom_drive_free()" */
int
cdda_close(cdrom_drive_t *d)
{
if(d){
if(d->opened)
d->enable_cdda(d,0);
_clean_messages(d);
if(d->cdda_device_name)free(d->cdda_device_name);
if(d->ioctl_device_name)free(d->ioctl_device_name);
if(d->drive_model)free(d->drive_model);
if(d->cdda_fd!=-1)close(d->cdda_fd);
if(d->ioctl_fd!=-1 && d->ioctl_fd!=d->cdda_fd)close(d->ioctl_fd);
if(d->sg)free(d->sg);
free(d);
}
return(0);
}
/* finish initializing the drive! */
int
cdda_open(cdrom_drive_t *d)
{
int ret;
if(d->opened)return(0);
switch(d->interface){
case GENERIC_SCSI:
if((ret=scsi_init_drive(d)))
return(ret);
break;
case COOKED_IOCTL:
if((ret=cooked_init_drive(d)))
return(ret);
break;
#ifdef CDDA_TEST
case TEST_INTERFACE:
if((ret=test_init_drive(d)))
return(ret);
break;
#endif
default:
cderror(d,"100: Interface not supported\n");
return(-100);
}
/* Check TOC, enable for CDDA */
/* Some drives happily return a TOC even if there is no disc... */
{
int i;
for(i=0;i<d->tracks;i++)
if(d->disc_toc[i].dwStartSector<0 ||
d->disc_toc[i+1].dwStartSector==0){
d->opened=0;
cderror(d,"009: CDROM reporting illegal table of contents\n");
return(-9);
}
}
if((ret=d->enable_cdda(d,1)))
return(ret);
/* d->select_speed(d,d->maxspeed); most drives are full speed by default */
if(d->bigendianp==-1)d->bigendianp=data_bigendianp(d);
return(0);
}
int
cdda_speed_set(cdrom_drive_t *d, int speed)
{
return d->set_speed ? d->set_speed(d, speed) : 0;
}
long cdda_read(cdrom_drive_t *d, void *buffer, long beginsector, long sectors)
{
if(d->opened){
if(sectors>0){
sectors=d->read_audio(d,buffer,beginsector,sectors);
if(sectors!=-1){
/* byteswap? */
if(d->bigendianp==-1) /* not determined yet */
d->bigendianp=data_bigendianp(d);
if(d->bigendianp!=bigendianp()){
int i;
u_int16_t *p=(u_int16_t *)buffer;
long els=sectors*CD_FRAMESIZE_RAW/2;
for(i=0;i<els;i++)p[i]=swap16(p[i]);
}
}
}
return(sectors);
}
cderror(d,"400: Device not open\n");
return(-400);
}
void
cdda_verbose_set(cdrom_drive_t *d,int err_action, int mes_action)
{
d->messagedest=mes_action;
d->errordest=err_action;
}
extern char *cdda_messages(cdrom_drive_t *d)
{
char *ret=d->messagebuf;
d->messagebuf=NULL;
return(ret);
}
extern char *cdda_errors(cdrom_drive_t *d)
{
char *ret=d->errorbuf;
d->errorbuf=NULL;
return(ret);
}

View File

@@ -0,0 +1,86 @@
/*
$Id: low_interface.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** internal include file for cdda interface kit for Linux */
#ifndef _CDDA_LOW_INTERFACE_
#define _CDDA_LOW_INTERFACE_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/types.h>
#include <linux/major.h>
#include <linux/version.h>
#include <cdio/paranoia.h>
#include <cdio/cdda_interface.h>
/* some include file locations have changed with newer kernels */
#ifdef SBPCD_H
#include <linux/sbpcd.h>
#endif
#ifdef UCDROM_H
#include <linux/ucdrom.h>
#endif
#ifndef CDROMAUDIOBUFSIZ
#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
#endif
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <linux/cdrom.h>
#include <linux/major.h>
#define MAX_RETRIES 8
#define MAX_BIG_BUFF_SIZE 65536
#define MIN_BIG_BUFF_SIZE 4096
#define SG_OFF sizeof(struct sg_header)
#ifndef SG_EMULATED_HOST
/* old kernel version; the check for the ioctl is still runtime, this
is just to build */
#define SG_EMULATED_HOST 0x2203
#define SG_SET_TRANSFORM 0x2204
#define SG_GET_TRANSFORM 0x2205
#endif
extern int cooked_init_drive (cdrom_drive_t *d);
extern unsigned char *scsi_inquiry (cdrom_drive_t *d);
extern int scsi_init_drive (cdrom_drive_t *d);
#ifdef CDDA_TEST
extern int test_init_drive (cdrom_drive_t *d);
#endif
#endif /*_CDDA_LOW_INTERFACE_*/

View File

@@ -0,0 +1,733 @@
/*
$Id: scan_devices.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
*
* Autoscan for or verify presence of a cdrom device
*
******************************************************************/
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "low_interface.h"
#include "common_interface.h"
#include "utils.h"
#define MAX_DEV_LEN 20 /* Safe because strings only come from below */
/* must be absolute paths! */
const char *scsi_cdrom_prefixes[]={
"/dev/scd",
"/dev/sr",
NULL};
const char *scsi_generic_prefixes[]={
"/dev/sg",
NULL};
const char *devfs_scsi_test="/dev/scsi/";
const char *devfs_scsi_cd="cd";
const char *devfs_scsi_generic="generic";
const char *cdrom_devices[]={
"/dev/cdrom",
"/dev/cdroms/cdrom?",
"/dev/hd?",
"/dev/sg?",
"/dev/cdu31a",
"/dev/cdu535",
"/dev/sbpcd",
"/dev/sbpcd?",
"/dev/sonycd",
"/dev/mcd",
"/dev/sjcd",
/* "/dev/aztcd", timeout is too long */
"/dev/cm206cd",
"/dev/gscd",
"/dev/optcd",NULL};
/* Functions here look for a cdrom drive; full init of a drive type
happens in interface.c */
cdrom_drive_t *
cdda_find_a_cdrom(int messagedest, char **messages){
/* Brute force... */
int i=0;
cdrom_drive_t *d;
while(cdrom_devices[i]!=NULL){
/* is it a name or a pattern? */
char *pos;
if((pos=strchr(cdrom_devices[i],'?'))){
int j;
/* try first eight of each device */
for(j=0;j<4;j++){
char *buffer=copystring(cdrom_devices[i]);
/* number, then letter */
buffer[pos-(cdrom_devices[i])]=j+48;
if((d=cdda_identify(buffer,messagedest,messages)))
return(d);
idmessage(messagedest,messages,"",NULL);
buffer[pos-(cdrom_devices[i])]=j+97;
if((d=cdda_identify(buffer,messagedest,messages)))
return(d);
idmessage(messagedest,messages,"",NULL);
}
}else{
/* Name. Go for it. */
if((d=cdda_identify(cdrom_devices[i],messagedest,messages)))
return(d);
idmessage(messagedest,messages,"",NULL);
}
i++;
}
{
struct passwd *temp;
temp=getpwuid(geteuid());
idmessage(messagedest,messages,
"\n\nNo cdrom drives accessible to %s found.\n",
temp->pw_name);
}
return(NULL);
}
cdrom_drive_t *
cdda_identify(const char *device, int messagedest,char **messages)
{
struct stat st;
cdrom_drive_t *d=NULL;
idmessage(messagedest,messages,"Checking %s for cdrom...",device);
if(stat(device,&st)){
idperror(messagedest,messages,"\tCould not stat %s",device);
return(NULL);
}
#ifndef CDDA_TEST
if (!S_ISCHR(st.st_mode) &&
!S_ISBLK(st.st_mode)){
idmessage(messagedest,messages,"\t%s is not a block or character device",device);
return(NULL);
}
#endif
d=cdda_identify_cooked(device,messagedest,messages);
if(!d)d=cdda_identify_scsi(device,NULL,messagedest,messages);
#ifdef CDDA_TEST
if(!d)d=cdda_identify_test(device,messagedest,messages);
#endif
return(d);
}
static char *
test_resolve_symlink(const char *file,int messagedest,char **messages)
{
char resolved[PATH_MAX];
struct stat st;
if(lstat(file,&st)){
idperror(messagedest,messages,"\t\tCould not stat %s",file);
return(NULL);
}
if(realpath(file,resolved))
return(strdup(resolved));
idperror(messagedest,messages,"\t\tCould not resolve symlink %s",file);
return(NULL);
}
cdrom_drive_t *
cdda_identify_cooked(const char *dev, int messagedest,
char **messages)
{
cdrom_drive_t *d=NULL;
struct stat st;
int fd=-1;
int type;
char *description=NULL;
char *device;
idmessage(messagedest,messages,"\tTesting %s for cooked ioctl() interface",dev);
device=test_resolve_symlink(dev,messagedest,messages);
if(device==NULL)return(NULL);
if(stat(device,&st)){
idperror(messagedest,messages,"\t\tCould not stat %s",device);
free(device);
return(NULL);
}
if (!S_ISCHR(st.st_mode) &&
!S_ISBLK(st.st_mode)){
idmessage(messagedest,messages,"\t\t%s is not a block or character device",device);
free(device);
return(NULL);
}
type=(int)(st.st_rdev>>8);
switch (type) {
case IDE0_MAJOR:
case IDE1_MAJOR:
case IDE2_MAJOR:
case IDE3_MAJOR:
/* Yay, ATAPI... */
/* Ping for CDROM-ness */
fd=open(device,O_RDONLY|O_NONBLOCK);
if(fd==-1){
idperror(messagedest,messages,"\t\tUnable to open %s",device);
free(device);
return(NULL);
}
if(ioctl_ping_cdrom(fd)){
idmessage(messagedest,messages,"\t\tDevice %s is not a CDROM",device);
close(fd);
free(device);
return(NULL);
}
{
char *temp=atapi_drive_info(fd);
description=catstring(NULL,"ATAPI compatible ");
description=catstring(description,temp);
free(temp);
}
break;
case CDU31A_CDROM_MAJOR:
/* major indicates this is a cdrom; no ping necessary. */
description=copystring("Sony CDU31A or compatible");
break;
case CDU535_CDROM_MAJOR:
/* major indicates this is a cdrom; no ping necessary. */
description=copystring("Sony CDU535 or compatible");
break;
case MATSUSHITA_CDROM_MAJOR:
case MATSUSHITA_CDROM2_MAJOR:
case MATSUSHITA_CDROM3_MAJOR:
case MATSUSHITA_CDROM4_MAJOR:
/* major indicates this is a cdrom; no ping necessary. */
description=copystring("non-ATAPI IDE-style Matsushita/Panasonic CR-5xx or compatible");
break;
case SANYO_CDROM_MAJOR:
description=copystring("Sanyo proprietary or compatible: NOT CDDA CAPABLE");
break;
case MITSUMI_CDROM_MAJOR:
case MITSUMI_X_CDROM_MAJOR:
description=copystring("Mitsumi proprietary or compatible: NOT CDDA CAPABLE");
break;
case OPTICS_CDROM_MAJOR:
description=copystring("Optics Dolphin or compatible: NOT CDDA CAPABLE");
break;
case AZTECH_CDROM_MAJOR:
description=copystring("Aztech proprietary or compatible: NOT CDDA CAPABLE");
break;
case GOLDSTAR_CDROM_MAJOR:
description=copystring("Goldstar proprietary: NOT CDDA CAPABLE");
break;
case CM206_CDROM_MAJOR:
description=copystring("Philips/LMS CM206 proprietary: NOT CDDA CAPABLE");
break;
case SCSI_CDROM_MAJOR:
case SCSI_GENERIC_MAJOR:
/* Nope nope nope */
idmessage(messagedest,messages,"\t\t%s is not a cooked ioctl CDROM.",device);
free(device);
return(NULL);
default:
/* What the hell is this? */
idmessage(messagedest,messages,"\t\t%s is not a cooked ioctl CDROM.",device);
free(device);
return(NULL);
}
if(fd==-1)fd=open(device,O_RDONLY|O_NONBLOCK);
if(fd==-1){
idperror(messagedest,messages,"\t\tUnable to open %s",device);
free(device);
if(description)free(description);
return(NULL);
}
/* Minimum init */
d=calloc(1,sizeof(cdrom_drive_t));
d->cdda_device_name=device;
d->ioctl_device_name=copystring(device);
d->drive_model=description;
d->drive_type=type;
d->cdda_fd=fd;
d->ioctl_fd=fd;
d->interface=COOKED_IOCTL;
d->bigendianp=-1; /* We don't know yet... */
d->nsectors=-1;
idmessage(messagedest,messages,"\t\tCDROM sensed: %s\n",description);
return(d);
}
struct sg_id {
long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */
long l2; /* Unique id */
} sg_id;
typedef struct scsiid{
int bus;
int id;
int lun;
} scsiid;
/* Even *this* isn't as simple as it bloody well should be :-P */
/* SG has an easy interface, but SCSI overall does not */
static int get_scsi_id(int fd, scsiid *id){
struct sg_id argid;
int busarg;
/* get the host/id/lun */
if(fd==-1)return(-1);
if(ioctl(fd,SCSI_IOCTL_GET_IDLUN,&argid))return(-1);
id->bus=argid.l2; /* for now */
id->id=argid.l1&0xff;
id->lun=(argid.l1>>8)&0xff;
if(ioctl(fd,SCSI_IOCTL_GET_BUS_NUMBER,&busarg)==0)
id->bus=busarg;
return(0);
}
/* slightly wasteful, but a clean abstraction */
static char *scsi_match(const char *device, const char **prefixes,
const char *devfs_test,
const char *devfs_other,
const char *prompt,
int messagedest,char **messages)
{
int dev=open(device,O_RDONLY|O_NONBLOCK);
scsiid a,b;
int i,j;
char buffer[200];
/* if we're running under /devfs, build the device name from the
device we already have */
if(!strncmp(device,devfs_test,strlen(devfs_test))){
char *pos;
strcpy(buffer,device);
pos=strrchr(buffer,'/');
if(pos){
int matchf;
sprintf(pos,"/%s",devfs_other);
matchf=open(buffer,O_RDONLY|O_NONBLOCK);
if(matchf!=-1){
close(matchf);
close(dev);
return(strdup(buffer));
}
}
}
/* get the host/id/lun */
if(dev==-1){
idperror(messagedest,messages,"\t\tCould not access device %s",
device);
goto matchfail;
}
if(get_scsi_id(dev,&a)){
idperror(messagedest,messages,"\t\tDevice %s could not perform ioctl()",
device);
goto matchfail;
}
/* go through most likely /dev nodes for a match */
for(i=0;i<25;i++){
for(j=0;j<2;j++){
int pattern=0;
int matchf;
while(prefixes[pattern]!=NULL){
switch(j){
case 0:
/* number */
sprintf(buffer,"%s%d",prefixes[pattern],i);
break;
case 1:
/* number */
sprintf(buffer,"%s%c",prefixes[pattern],i+'a');
break;
}
matchf=open(buffer,O_RDONLY|O_NONBLOCK);
if(matchf!=-1){
if(get_scsi_id(matchf,&b)==0){
if(a.bus==b.bus && a.id==b.id && a.lun==b.lun){
close(matchf);
close(dev);
return(strdup(buffer));
}
}
close(matchf);
}
pattern++;
}
}
}
idmessage(messagedest,messages,prompt,device);
matchfail:
if(dev!=-1)close(dev);
return(NULL);
}
static void
strscat(char *a,char *b,int n)
{
int i;
for(i=n;i>0;i--)
if(b[i-1]>' ')break;
strncat(a,b,i);
strcat(a," ");
}
/* At this point, we're going to punt compatability before SG2, and
allow only SG2 and SG3 */
static int verify_SG_version(cdrom_drive_t *d,int messagedest,
char **messages){
/* are we using the new SG driver by Doug Gilbert? If not, punt */
int version,major,minor;
char buffer[256];
idmessage(messagedest,messages,
"\nFound an accessible SCSI CDROM drive."
"\nLooking at revision of the SG interface in use...","");
if(ioctl(d->cdda_fd,SG_GET_VERSION_NUM,&version)){
/* Up, guess not. */
idmessage(messagedest,messages,
"\tOOPS! Old 2.0/early 2.1/early 2.2.x (non-ac patch) style "
"SG.\n\tCdparanoia no longer supports the old interface.\n","");
return(0);
}
major=version/10000;
version-=major*10000;
minor=version/100;
version-=minor*100;
sprintf(buffer,"\tSG interface version %d.%d.%d; OK.",
major,minor,version);
idmessage(messagedest,messages,buffer,"");
return(major);
}
cdrom_drive_t *
cdda_identify_scsi(const char *generic_device,
const char *ioctl_device, int messagedest,
char **messages)
{
cdrom_drive_t *d=NULL;
struct stat i_st;
struct stat g_st;
int i_fd=-1;
int g_fd=-1;
int version;
int type=-1;
char *p;
if(generic_device)
idmessage(messagedest,messages,"\tTesting %s for SCSI interface",
generic_device);
else
if(ioctl_device)
idmessage(messagedest,messages,"\tTesting %s for SCSI interface",
ioctl_device);
/* Do this first; it's wasteful, but the messages make more sense */
if(generic_device){
if(stat(generic_device,&g_st)){
idperror(messagedest,messages,"\t\tCould not access device %s",
generic_device);
return(NULL);
}
if((int)(g_st.st_rdev>>8)!=SCSI_GENERIC_MAJOR){
if((int)(g_st.st_rdev>>8)!=SCSI_CDROM_MAJOR){
idmessage(messagedest,messages,"\t\t%s is not a SCSI device",
generic_device);
return(NULL);
}else{
char *temp=(char *)generic_device;
generic_device=ioctl_device;
ioctl_device=temp;
}
}
}
if(ioctl_device){
if(stat(ioctl_device,&i_st)){
idperror(messagedest,messages,"\t\tCould not access device %s",
ioctl_device);
return(NULL);
}
if((int)(i_st.st_rdev>>8)!=SCSI_CDROM_MAJOR){
if((int)(i_st.st_rdev>>8)!=SCSI_GENERIC_MAJOR){
idmessage(messagedest,messages,"\t\t%s is not a SCSI device",
ioctl_device);
return(NULL);
}else{
char *temp=(char *)generic_device;
generic_device=ioctl_device;
ioctl_device=temp;
}
}
}
/* we need to resolve any symlinks for the lookup code to work */
if(generic_device){
generic_device=test_resolve_symlink(generic_device,messagedest,messages);
if(generic_device==NULL)goto cdda_identify_scsi_fail;
}
if(ioctl_device){
ioctl_device=test_resolve_symlink(ioctl_device,messagedest,messages);
if(ioctl_device==NULL)goto cdda_identify_scsi_fail;
}
if(!generic_device || !ioctl_device){
if(generic_device){
ioctl_device=
scsi_match(generic_device, scsi_cdrom_prefixes,
devfs_scsi_test, devfs_scsi_cd,
"\t\tNo cdrom device found to match generic device %s",
messagedest, messages);
}else{
generic_device=
scsi_match(ioctl_device,scsi_generic_prefixes,
devfs_scsi_test,devfs_scsi_generic,
"\t\tNo generic SCSI device found to match CDROM device %s",
messagedest,messages);
if(!generic_device)
goto cdda_identify_scsi_fail;
}
}
idmessage(messagedest,messages,"\t\tgeneric device: %s",generic_device);
idmessage(messagedest,messages,"\t\tioctl device: %s",(ioctl_device?
ioctl_device:
"not found"));
if(stat(generic_device,&g_st)){
idperror(messagedest,messages,"\t\tCould not access generic SCSI device "
"%s",generic_device);
goto cdda_identify_scsi_fail;
}
if(ioctl_device)i_fd=open(ioctl_device,O_RDONLY|O_NONBLOCK);
g_fd=open(generic_device,O_RDWR);
if(ioctl_device && i_fd==-1)
idperror(messagedest,messages,"\t\tCould not open SCSI cdrom device "
"%s (continuing)",ioctl_device);
if(g_fd==-1){
idperror(messagedest,messages,"\t\tCould not open generic SCSI device "
"%s",generic_device);
goto cdda_identify_scsi_fail;
}
if(i_fd!=-1){
if(stat(ioctl_device,&i_st)){
idperror(messagedest,messages,"\t\tCould not access SCSI cdrom device "
"%s",ioctl_device);
goto cdda_identify_scsi_fail;
}
type=(int)(i_st.st_rdev>>8);
if(type==SCSI_CDROM_MAJOR){
if (!S_ISBLK(i_st.st_mode)) {
idmessage(messagedest,messages,"\t\tSCSI CDROM device %s not a "
"block device",ioctl_device);
goto cdda_identify_scsi_fail;
}
}else{
idmessage(messagedest,messages,"\t\tSCSI CDROM device %s has wrong "
"major number",ioctl_device);
goto cdda_identify_scsi_fail;
}
}
if((int)(g_st.st_rdev>>8)==SCSI_GENERIC_MAJOR){
if (!S_ISCHR(g_st.st_mode)) {
idmessage(messagedest,messages,"\t\tGeneric SCSI device %s not a "
"char device",generic_device);
goto cdda_identify_scsi_fail;
}
}else{
idmessage(messagedest,messages,"\t\tGeneric SCSI device %s has wrong "
"major number",generic_device);
goto cdda_identify_scsi_fail;
}
d=calloc(1,sizeof(cdrom_drive_t));
d->drive_type=type;
d->cdda_fd=g_fd;
d->ioctl_fd=i_fd;
d->bigendianp=-1; /* We don't know yet... */
d->nsectors=-1;
version=verify_SG_version(d,messagedest,messages);
switch(version){
case -1:case 0:case 1:
d->interface=GENERIC_SCSI;
goto cdda_identify_scsi_fail;
case 2:case 3:
d->interface=GENERIC_SCSI;
break;
}
/* malloc our big buffer for scsi commands */
d->sg=malloc(MAX_BIG_BUFF_SIZE);
d->sg_buffer=d->sg+SG_OFF;
{
/* get the lun */
scsiid lun;
if(get_scsi_id(i_fd,&lun))
d->lun=0; /* a reasonable guess on a failed ioctl */
else
d->lun=lun.lun;
}
p = scsi_inquiry(d);
/* It would seem some TOSHIBA CDROMs gets things wrong */
if (!strncmp (p + 8, "TOSHIBA", 7) &&
!strncmp (p + 16, "CD-ROM", 6) &&
p[0] == TYPE_DISK) {
p[0] = TYPE_ROM;
p[1] |= 0x80; /* removable */
}
if (!p || (*p != TYPE_ROM && *p != TYPE_WORM)) {
idmessage(messagedest,messages,
"\t\tDrive is neither a CDROM nor a WORM device\n",NULL);
free(d->sg);
free(d);
goto cdda_identify_scsi_fail;
}
d->drive_model=calloc(36,1);
memcpy(d->inqbytes,p,4);
d->cdda_device_name=copystring(generic_device);
d->ioctl_device_name=copystring(ioctl_device);
d->drive_model=calloc(36,1);
strscat(d->drive_model,p+8,8);
strscat(d->drive_model,p+16,16);
strscat(d->drive_model,p+32,4);
idmessage(messagedest,messages,"\nCDROM model sensed sensed: %s",d->drive_model);
return(d);
cdda_identify_scsi_fail:
if(generic_device)free((char *)generic_device);
if(ioctl_device)free((char *)ioctl_device);
if(i_fd!=-1)close(i_fd);
if(g_fd!=-1)close(g_fd);
return(NULL);
}
#ifdef CDDA_TEST
cdrom_drive_t *cdda_identify_test(const char *filename, int messagedest,
char **messages){
cdrom_drive_t *d=NULL;
struct stat st;
int fd=-1;
idmessage(messagedest,messages,"\tTesting %s for file/test interface",
filename);
if(stat(filename,&st)){
idperror(messagedest,messages,"\t\tCould not access file %s",
filename);
return(NULL);
}
if(!S_ISREG(st.st_mode)){
idmessage(messagedest,messages,"\t\t%s is not a regular file",
filename);
return(NULL);
}
fd=open(filename,O_RDONLY);
if(fd==-1){
idperror(messagedest,messages,"\t\tCould not open file %s",filename);
return(NULL);
}
d=calloc(1,sizeof(cdrom_drive_t));
d->cdda_device_name=copystring(filename);
d->ioctl_device_name=copystring(filename);
d->drive_type=-1;
d->cdda_fd=fd;
d->ioctl_fd=fd;
d->interface=TEST_INTERFACE;
d->bigendianp=-1; /* We don't know yet... */
d->nsectors=-1;
d->drive_model=copystring("File based test interface");
idmessage(messagedest,messages,"\t\tCDROM sensed: %s\n",d->drive_model);
return(d);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,547 @@
/******************************************************************
* CopyPolicy: GNU Public License 2 applies
* Copyright (C) 1998 Monty xiphmont@mit.edu
*
* FFT implementation from OggSquish, minus cosine transforms,
* minus all but radix 2/4 case
*
* See OggSquish or NetLib for the version that can do other than just
* power-of-two sized vectors.
*
******************************************************************/
#include <stdlib.h>
#include <math.h>
#include "smallft.h"
static void drfti1(int n, float *wa, int *ifac){
static int ntryh[4] = { 4,2,3,5 };
static float tpi = 6.28318530717958647692528676655900577;
float arg,argh,argld,fi;
int ntry=0,i,j=-1;
int k1, l1, l2, ib;
int ld, ii, ip, is, nq, nr;
int ido, ipm, nfm1;
int nl=n;
int nf=0;
L101:
j++;
if (j < 4)
ntry=ntryh[j];
else
ntry+=2;
L104:
nq=nl/ntry;
nr=nl-ntry*nq;
if (nr!=0) goto L101;
nf++;
ifac[nf+1]=ntry;
nl=nq;
if(ntry!=2)goto L107;
if(nf==1)goto L107;
for (i=1;i<nf;i++){
ib=nf-i+1;
ifac[ib+1]=ifac[ib];
}
ifac[2] = 2;
L107:
if(nl!=1)goto L104;
ifac[0]=n;
ifac[1]=nf;
argh=tpi/n;
is=0;
nfm1=nf-1;
l1=1;
if(nfm1==0)return;
for (k1=0;k1<nfm1;k1++){
ip=ifac[k1+2];
ld=0;
l2=l1*ip;
ido=n/l2;
ipm=ip-1;
for (j=0;j<ipm;j++){
ld+=l1;
i=is;
argld=(float)ld*argh;
fi=0.;
for (ii=2;ii<ido;ii+=2){
fi+=1.;
arg=fi*argld;
wa[i++]=cos(arg);
wa[i++]=sin(arg);
}
is+=ido;
}
l1=l2;
}
}
static void fdrffti(int n, float *wsave, int *ifac){
if (n == 1) return;
drfti1(n, wsave+n, ifac);
}
static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
int i,k;
float ti2,tr2;
int t0,t1,t2,t3,t4,t5,t6;
t1=0;
t0=(t2=l1*ido);
t3=ido<<1;
for(k=0;k<l1;k++){
ch[t1<<1]=cc[t1]+cc[t2];
ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
t1+=ido;
t2+=ido;
}
if(ido<2)return;
if(ido==2)goto L105;
t1=0;
t2=t0;
for(k=0;k<l1;k++){
t3=t2;
t4=(t1<<1)+(ido<<1);
t5=t1;
t6=t1+t1;
for(i=2;i<ido;i+=2){
t3+=2;
t4-=2;
t5+=2;
t6+=2;
tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
ch[t6]=cc[t5]+ti2;
ch[t4]=ti2-cc[t5];
ch[t6-1]=cc[t5-1]+tr2;
ch[t4-1]=cc[t5-1]-tr2;
}
t1+=ido;
t2+=ido;
}
if(ido%2==1)return;
L105:
t3=(t2=(t1=ido)-1);
t2+=t0;
for(k=0;k<l1;k++){
ch[t1]=-cc[t2];
ch[t1-1]=cc[t3];
t1+=ido<<1;
t2+=ido;
t3+=ido;
}
}
static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
float *wa2,float *wa3){
static float hsqt2 = .70710678118654752440084436210485;
int i,k,t0,t1,t2,t3,t4,t5,t6;
float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
t0=l1*ido;
t1=t0;
t4=t1<<1;
t2=t1+(t1<<1);
t3=0;
for(k=0;k<l1;k++){
tr1=cc[t1]+cc[t2];
tr2=cc[t3]+cc[t4];
ch[t5=t3<<2]=tr1+tr2;
ch[(ido<<2)+t5-1]=tr2-tr1;
ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
ch[t5]=cc[t2]-cc[t1];
t1+=ido;
t2+=ido;
t3+=ido;
t4+=ido;
}
if(ido<2)return;
if(ido==2)goto L105;
t1=0;
for(k=0;k<l1;k++){
t2=t1;
t4=t1<<2;
t5=(t6=ido<<1)+t4;
for(i=2;i<ido;i+=2){
t3=(t2+=2);
t4+=2;
t5-=2;
t3+=t0;
cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
t3+=t0;
cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
t3+=t0;
cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
tr1=cr2+cr4;
tr4=cr4-cr2;
ti1=ci2+ci4;
ti4=ci2-ci4;
ti2=cc[t2]+ci3;
ti3=cc[t2]-ci3;
tr2=cc[t2-1]+cr3;
tr3=cc[t2-1]-cr3;
ch[t4-1]=tr1+tr2;
ch[t4]=ti1+ti2;
ch[t5-1]=tr3-ti4;
ch[t5]=tr4-ti3;
ch[t4+t6-1]=ti4+tr3;
ch[t4+t6]=tr4+ti3;
ch[t5+t6-1]=tr2-tr1;
ch[t5+t6]=ti1-ti2;
}
t1+=ido;
}
if(ido&1)return;
L105:
t2=(t1=t0+ido-1)+(t0<<1);
t3=ido<<2;
t4=ido;
t5=ido<<1;
t6=ido;
for(k=0;k<l1;k++){
ti1=-hsqt2*(cc[t1]+cc[t2]);
tr1=hsqt2*(cc[t1]-cc[t2]);
ch[t4-1]=tr1+cc[t6-1];
ch[t4+t5-1]=cc[t6-1]-tr1;
ch[t4]=ti1-cc[t1+t0];
ch[t4+t5]=ti1+cc[t1+t0];
t1+=ido;
t2+=ido;
t4+=t3;
t6+=ido;
}
}
static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
int i,k1,l1,l2;
int na,kh,nf;
int ip,iw,ido,idl1,ix2,ix3;
nf=ifac[1];
na=1;
l2=n;
iw=n;
for(k1=0;k1<nf;k1++){
kh=nf-k1;
ip=ifac[kh+1];
l1=l2/ip;
ido=n/l2;
idl1=ido*l1;
iw-=(ip-1)*ido;
na=1-na;
if(ip!=4)goto L102;
ix2=iw+ido;
ix3=ix2+ido;
if(na!=0)
dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
else
dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
goto L110;
L102:
if(ip!=2)goto L104;
if(na!=0)goto L103;
dradf2(ido,l1,c,ch,wa+iw-1);
goto L110;
L103:
dradf2(ido,l1,ch,c,wa+iw-1);
goto L110;
L104:
return; /* We're restricted to powers of two. just fail */
L110:
l2=l1;
}
if(na==1)return;
for(i=0;i<n;i++)c[i]=ch[i];
}
static void fdrfftf(int n,float *r,float *wsave,int *ifac){
if(n==1)return;
drftf1(n,r,wsave,wsave+n,ifac);
}
static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
int i,k,t0,t1,t2,t3,t4,t5,t6;
float ti2,tr2;
t0=l1*ido;
t1=0;
t2=0;
t3=(ido<<1)-1;
for(k=0;k<l1;k++){
ch[t1]=cc[t2]+cc[t3+t2];
ch[t1+t0]=cc[t2]-cc[t3+t2];
t2=(t1+=ido)<<1;
}
if(ido<2)return;
if(ido==2)goto L105;
t1=0;
t2=0;
for(k=0;k<l1;k++){
t3=t1;
t5=(t4=t2)+(ido<<1);
t6=t0+t1;
for(i=2;i<ido;i+=2){
t3+=2;
t4+=2;
t5-=2;
t6+=2;
ch[t3-1]=cc[t4-1]+cc[t5-1];
tr2=cc[t4-1]-cc[t5-1];
ch[t3]=cc[t4]-cc[t5];
ti2=cc[t4]+cc[t5];
ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
}
t2=(t1+=ido)<<1;
}
if(ido%2==1)return;
L105:
t1=ido-1;
t2=ido-1;
for(k=0;k<l1;k++){
ch[t1]=cc[t2]+cc[t2];
ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
t1+=ido;
t2+=ido<<1;
}
}
static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
float *wa2,float *wa3){
static float sqrt2=1.4142135623730950488016887242097;
int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
t0=l1*ido;
t1=0;
t2=ido<<2;
t3=0;
t6=ido<<1;
for(k=0;k<l1;k++){
t4=t3+t6;
t5=t1;
tr3=cc[t4-1]+cc[t4-1];
tr4=cc[t4]+cc[t4];
tr1=cc[t3]-cc[(t4+=t6)-1];
tr2=cc[t3]+cc[t4-1];
ch[t5]=tr2+tr3;
ch[t5+=t0]=tr1-tr4;
ch[t5+=t0]=tr2-tr3;
ch[t5+=t0]=tr1+tr4;
t1+=ido;
t3+=t2;
}
if(ido<2)return;
if(ido==2)goto L105;
t1=0;
for(k=0;k<l1;k++){
t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
t7=t1;
for(i=2;i<ido;i+=2){
t2+=2;
t3+=2;
t4-=2;
t5-=2;
t7+=2;
ti1=cc[t2]+cc[t5];
ti2=cc[t2]-cc[t5];
ti3=cc[t3]-cc[t4];
tr4=cc[t3]+cc[t4];
tr1=cc[t2-1]-cc[t5-1];
tr2=cc[t2-1]+cc[t5-1];
ti4=cc[t3-1]-cc[t4-1];
tr3=cc[t3-1]+cc[t4-1];
ch[t7-1]=tr2+tr3;
cr3=tr2-tr3;
ch[t7]=ti2+ti3;
ci3=ti2-ti3;
cr2=tr1-tr4;
cr4=tr1+tr4;
ci2=ti1+ti4;
ci4=ti1-ti4;
ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
}
t1+=ido;
}
if(ido%2 == 1)return;
L105:
t1=ido;
t2=ido<<2;
t3=ido-1;
t4=ido+(ido<<1);
for(k=0;k<l1;k++){
t5=t3;
ti1=cc[t1]+cc[t4];
ti2=cc[t4]-cc[t1];
tr1=cc[t1-1]-cc[t4-1];
tr2=cc[t1-1]+cc[t4-1];
ch[t5]=tr2+tr2;
ch[t5+=t0]=sqrt2*(tr1-ti1);
ch[t5+=t0]=ti2+ti2;
ch[t5+=t0]=-sqrt2*(tr1+ti1);
t3+=ido;
t1+=t2;
t4+=t2;
}
}
static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
int i,k1,l1,l2;
int na;
int nf,ip,iw,ix2,ix3,ido,idl1;
nf=ifac[1];
na=0;
l1=1;
iw=1;
for(k1=0;k1<nf;k1++){
ip=ifac[k1 + 2];
l2=ip*l1;
ido=n/l2;
idl1=ido*l1;
if(ip!=4)goto L103;
ix2=iw+ido;
ix3=ix2+ido;
if(na!=0)
dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
else
dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
na=1-na;
goto L115;
L103:
if(ip!=2)goto L106;
if(na!=0)
dradb2(ido,l1,ch,c,wa+iw-1);
else
dradb2(ido,l1,c,ch,wa+iw-1);
na=1-na;
goto L115;
L106:
return; /* silently fail. we only do powers of two in this version */
L115:
l1=l2;
iw+=(ip-1)*ido;
}
if(na==0)return;
for(i=0;i<n;i++)c[i]=ch[i];
}
static void fdrfftb(int n, float *r, float *wsave, int *ifac){
if (n == 1)return;
drftb1(n, r, wsave, wsave+n, ifac);
}
void fft_forward(int n, float *buf,float *trigcache,int *splitcache){
int flag=0;
if(!trigcache || !splitcache){
trigcache=calloc(3*n,sizeof(float));
splitcache=calloc(32,sizeof(int));
fdrffti(n, trigcache, splitcache);
flag=1;
}
fdrfftf(n, buf, trigcache, splitcache);
if(flag){
free(trigcache);
free(splitcache);
}
}
void fft_backward(int n, float *buf, float *trigcache,int *splitcache){
int i;
int flag=0;
if(!trigcache || !splitcache){
trigcache=calloc(3*n,sizeof(float));
splitcache=calloc(32,sizeof(int));
fdrffti(n, trigcache, splitcache);
flag=1;
}
fdrfftb(n, buf, trigcache, splitcache);
for(i=0;i<n;i++)buf[i]/=n;
if(flag){
free(trigcache);
free(splitcache);
}
}
void fft_i(int n, float **trigcache, int **splitcache){
*trigcache=calloc(3*n,sizeof(float));
*splitcache=calloc(32,sizeof(int));
fdrffti(n, *trigcache, *splitcache);
}

View File

@@ -0,0 +1,12 @@
/******************************************************************
* CopyPolicy: GNU Public License 2 applies
* Copyright (C) 1998 Monty xiphmont@mit.edu
*
* FFT implementation from OggSquish, minus cosine transforms.
* Only convenience functions exposed
*
******************************************************************/
extern void fft_forward(int n, float *buf, float *trigcache, int *sp);
extern void fft_backward(int n, float *buf, float *trigcache, int *sp);
extern void fft_i(int n, float **trigcache, int **splitcache);

View File

@@ -0,0 +1,238 @@
/*
$Id: test_interface.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
*
* Fake interface backend for testing paranoia layer
*
******************************************************************/
#ifdef CDDA_TEST
#include "low_interface.h"
#include "utils.h"
/* Build which test model? */
#define CDDA_TEST_OK
#undef CDDA_TEST_JITTER_SMALL
#undef CDDA_TEST_JITTER_LARGE
#undef CDDA_TEST_JITTER_MASSIVE
#undef CDDA_TEST_FRAG_SMALL
#undef CDDA_TEST_FRAG_LARGE
#undef CDDA_TEST_FRAG_MASSIVE
#undef CDDA_TEST_BOGUS_BYTES
#undef CDDA_TEST_DROPDUPE_BYTES
#undef CDDA_TEST_SCRATCH
#undef CDDA_TEST_UNDERRUN
#undef CDDA_TEST_ALLJITTER
#undef CDDA_TEST_SOMEJITTER
#undef CDDA_TEST_SEEKJITTER
static int test_readtoc (cdrom_drive *d){
int tracks=0;
long bytes;
long sectors;
/* only one track, as many sectors as the file */
bytes=lseek(d->cdda_fd,0,SEEK_END);
lseek(d->cdda_fd,0,SEEK_SET);
sectors=bytes/CDIO_CD_FRAMESIZE_RAW;
d->disc_toc[0].bFlags = 0;
d->disc_toc[0].bTrack = 1;
d->disc_toc[0].dwStartSector = 37;
d->disc_toc[1].bFlags = 0x4;
d->disc_toc[1].bTrack = CDROM_LEADOUT;
d->disc_toc[1].dwStartSector = sectors+37;
tracks=2;
d->cd_extra=0;
return(--tracks); /* without lead-out */
}
/* we emulate jitter, scratches, atomic jitter and bogus bytes on
boundaries, etc */
static long
test_read(cdrom_drive *d, void *p, long begin, long sectors)
{
#if defined(CDDA_TEST_SEEKJITTER) \
|| defined(CDDA_TEST_ALLJITTER) \
|| defined(CDDA_TEST_SOMEJITTER)
int jitter_flag=0;
#endif
int los_flag=0;
static int jitter=0;
int bytes_so_far=0;
long bytestotal;
static FILE *fd=NULL;
static long lastread=0;
if(!fd)fd=fdopen(d->cdda_fd,"r");
#ifdef CDDA_TEST_UNDERRUN
sectors-=1;
#endif
#ifdef CDDA_TEST_SEEKJITTER
if(lastread!=begin)jitter_flag=1;
#else
#ifdef CDDA_TEST_ALLJITTER
jitter_flag=1;
#else
#ifdef CDDA_TEST_SOMEJITTER
jitter_flag=(drand48()>.9?1:0);
los_flag=(drand48()>.9?1:0);
#else
los_flag=1;
#endif
#endif
#endif
lastread=begin+sectors;
bytestotal=sectors*CDIO_CD_FRAMESIZE_RAW;
begin*=CDIO_CD_FRAMESIZE_RAW;
while(bytes_so_far<bytestotal){
int inner_bytes=bytestotal-bytes_so_far;
char *inner_buf=(char *)p + bytes_so_far;
long seeki;
long rbytes;
long this_bytes=inner_bytes;
#ifdef CDDA_TEST_OK
#else
#ifdef CDDA_TEST_JITTER_SMALL
if(jitter_flag)jitter=4*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_JITTER_LARGE
if(jitter_flag)jitter=32*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_JITTER_MASSIVE
if(jitter_flag)jitter=128*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_FRAG_SMALL
if(los_flag)this_bytes=256*(int)(drand48()*CDIO_CD_FRAMESIZE_RAW/8);
if(jitter_flag)jitter=4*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_FRAG_LARGE
if(los_flag)this_bytes=16*(int)(drand48()*CDIO_CD_FRAMESIZE_RAW/8);
if(jitter_flag)jitter=4*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_FRAG_MASSIVE
if(los_flag)this_bytes=8*(int)(drand48()*CDIO_CD_FRAMESIZE_RAW/8);
if(jitter_flag)jitter=32*(int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
#ifdef CDDA_TEST_DROPDUPE_BYTES
if(los_flag)this_bytes=CDIO_CD_FRAMESIZE_RAW;
if(jitter_flag)
if (drand48()>.8)
this_jitter=32;
else
this_jitter=0;
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
if(this_bytes>inner_bytes)this_bytes=inner_bytes;
if(begin+jitter+bytes_so_far<0)jitter=0;
seeki=begin+bytes_so_far+jitter;
if(fseek(fd,seeki,SEEK_SET)<0){
return(0);
}
rbytes=fread(inner_buf,1,this_bytes,fd);
bytes_so_far+=rbytes;
if(rbytes==0)break;
#ifdef CDDA_TEST_SEEKJITTER
jitter_flag=0;
los_flag=0;
#else
#ifdef CDDA_TEST_ALLJITTER
jitter_flag=1;
los_flag=0;
#else
#ifdef CDDA_TEST_SOMEJITTER
jitter_flag=(drand48()>.9?1:0);
los_flag=(drand48()>.9?1:0);
#else
los_flag=1;
#endif
#endif
#endif
}
#ifdef CDDA_TEST_SCRATCH
{
long location=300*CDIO_CD_FRAMESIZE_RAW+(drand48()*56)+512;
if(begin<=location && begin+bytestotal>location){
memset(p+location-begin,(int)(drand48()*256),1100);
}
}
#endif
return(sectors);
}
/* hook */
static int Dummy (cdrom_drive *d,int Switch){
return(0);
}
/* set function pointers to use the ioctl routines */
int test_init_drive (cdrom_drive *d){
d->nsectors=13;
d->enable_cdda = Dummy;
d->read_audio = test_read;
d->read_toc = test_readtoc;
d->set_speed = Dummy;
d->tracks=d->read_toc(d);
if(d->tracks==-1)
return(d->tracks);
d->opened=1;
srand48(0);
return(0);
}
#endif

199
lib/cdda_interface/toc.c Normal file
View File

@@ -0,0 +1,199 @@
/*
$Id: toc.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 1998 Monty xiphmont@mit.edu
derived from code (C) 1994-1996 Heiko Eissfeldt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
* Table of contents convenience functions
******************************************************************/
#include "low_interface.h"
#include "utils.h"
long
cdda_track_firstsector(cdrom_drive_t *d,int track)
{
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
if (track == 0) {
if (d->disc_toc[0].dwStartSector == 0) {
/* first track starts at lba 0 -> no pre-gap */
cderror(d,"401: Invalid track number\n");
return(-1);
}
else {
return 0; /* pre-gap of first track always starts at lba 0 */
}
}
if(track<0 || track>d->tracks){
cderror(d,"401: Invalid track number\n");
return(-1);
}
return(d->disc_toc[track-1].dwStartSector);
}
long
cdda_disc_firstsector(cdrom_drive_t *d)
{
int i;
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
/* look for an audio track */
for(i=0;i<d->tracks;i++)
if(cdda_track_audiop(d,i+1)==1) {
if (i == 0) /* disc starts at lba 0 if first track is an audio track */
return 0;
else
return(cdda_track_firstsector(d,i+1));
}
cderror(d,"403: No audio tracks on disc\n");
return(-1);
}
long
cdda_track_lastsector(cdrom_drive_t *d,int track)
{
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
if (track == 0) {
if (d->disc_toc[0].dwStartSector == 0) {
/* first track starts at lba 0 -> no pre-gap */
cderror(d,"401: Invalid track number\n");
return(-1);
}
else {
return d->disc_toc[0].dwStartSector-1;
}
}
if(track<1 || track>d->tracks){
cderror(d,"401: Invalid track number\n");
return(-1);
}
/* Safe, we've always the leadout at disc_toc[tracks] */
return(d->disc_toc[track].dwStartSector-1);
}
long
cdda_disc_lastsector(cdrom_drive_t *d)
{
int i;
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
/* look for an audio track */
for(i=d->tracks-1;i>=0;i--)
if(cdda_track_audiop(d,i+1)==1)
return(cdda_track_lastsector(d,i+1));
cderror(d,"403: No audio tracks on disc\n");
return(-1);
}
long
cdda_tracks(cdrom_drive_t *d)
{
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
return(d->tracks);
}
int
cdda_sector_gettrack(cdrom_drive_t *d,long sector)
{
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}else{
int i;
if (sector < d->disc_toc[0].dwStartSector)
return 0; /* We're in the pre-gap of first track */
for(i=0;i<d->tracks;i++){
if(d->disc_toc[i].dwStartSector<=sector &&
d->disc_toc[i+1].dwStartSector>sector)
return (i+1);
}
cderror(d,"401: Invalid track number\n");
return -1;
}
}
static int
cdda_track_bitmap(cdrom_drive_t *d,int track,int bit,int set,int clear)
{
if(!d->opened){
cderror(d,"400: Device not open\n");
return(-1);
}
if (track == 0)
track = 1; /* map to first track number */
if(track<1 || track>d->tracks){
cderror(d,"401: Invalid track number\n");
return(-1);
}
if ((d->disc_toc[track-1].bFlags & bit))
return(set);
else
return(clear);
}
int
cdda_track_channels(cdrom_drive_t *d,int track)
{
return(cdda_track_bitmap(d,track,8,4,2));
}
int
cdda_track_audiop(cdrom_drive_t *d,int track)
{
return(cdda_track_bitmap(d,track,4,0,1));
}
int
cdda_track_copyp(cdrom_drive_t *d,int track)
{
return(cdda_track_bitmap(d,track,2,1,0));
}
int
cdda_track_preemp(cdrom_drive_t *d, int track)
{
return(cdda_track_bitmap(d,track,1,1,0));
}

138
lib/cdda_interface/utils.c Normal file
View File

@@ -0,0 +1,138 @@
/*
$Id: utils.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common_interface.h"
#include "utils.h"
void
cderror(cdrom_drive_t *d,const char *s)
{
if(s && d){
switch(d->errordest){
case CDDA_MESSAGE_PRINTIT:
write(STDERR_FILENO,s,strlen(s));
break;
case CDDA_MESSAGE_LOGIT:
d->errorbuf=catstring(d->errorbuf,s);
break;
case CDDA_MESSAGE_FORGETIT:
default: ;
}
}
}
void
cdmessage(cdrom_drive_t *d, const char *s)
{
if(s && d){
switch(d->messagedest){
case CDDA_MESSAGE_PRINTIT:
write(STDERR_FILENO,s,strlen(s));
break;
case CDDA_MESSAGE_LOGIT:
d->messagebuf=catstring(d->messagebuf,s);
break;
case CDDA_MESSAGE_FORGETIT:
default: ;
}
}
}
void
idperror(int messagedest,char **messages,const char *f,
const char *s)
{
char *buffer;
int malloced=0;
if(!f)
buffer=(char *)s;
else
if(!s)
buffer=(char *)f;
else{
buffer=malloc(strlen(f)+strlen(s)+9);
sprintf(buffer,f,s);
malloced=1;
}
if(buffer){
switch(messagedest){
case CDDA_MESSAGE_PRINTIT:
write(STDERR_FILENO,buffer,strlen(buffer));
if(errno){
write(STDERR_FILENO,": ",2);
write(STDERR_FILENO,strerror(errno),strlen(strerror(errno)));
write(STDERR_FILENO,"\n",1);
}
break;
case CDDA_MESSAGE_LOGIT:
if(messages){
*messages=catstring(*messages,buffer);
if(errno){
*messages=catstring(*messages,": ");
*messages=catstring(*messages,strerror(errno));
*messages=catstring(*messages,"\n");
}
}
break;
case CDDA_MESSAGE_FORGETIT:
default: ;
}
}
if(malloced)free(buffer);
}
void
idmessage(int messagedest,char **messages,const char *f,
const char *s)
{
char *buffer;
int malloced=0;
if(!f)
buffer=(char *)s;
else
if(!s)
buffer=(char *)f;
else{
buffer=malloc(strlen(f)+strlen(s)+10);
sprintf(buffer,f,s);
strcat(buffer,"\n");
malloced=1;
}
if(buffer){
switch(messagedest){
case CDDA_MESSAGE_PRINTIT:
write(STDERR_FILENO,buffer,strlen(buffer));
if(!malloced)write(STDERR_FILENO,"\n",1);
break;
case CDDA_MESSAGE_LOGIT:
if(messages){
*messages=catstring(*messages,buffer);
if(!malloced)*messages=catstring(*messages,"\n");
}
break;
case CDDA_MESSAGE_FORGETIT:
default: ;
}
}
if(malloced)free(buffer);
}

133
lib/cdda_interface/utils.h Normal file
View File

@@ -0,0 +1,133 @@
/*
$Id: utils.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <endian.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <cdio/types.h>
/* I wonder how many alignment issues this is gonna trip in the
future... it shouldn't trip any... I guess we'll find out :) */
static inline int bigendianp(void){
int test=1;
char *hack=(char *)(&test);
if(hack[0])return(0);
return(1);
}
static inline int32_t swap32(int32_t x){
return((((u_int32_t)x & 0x000000ffU) << 24) |
(((u_int32_t)x & 0x0000ff00U) << 8) |
(((u_int32_t)x & 0x00ff0000U) >> 8) |
(((u_int32_t)x & 0xff000000U) >> 24));
}
static inline int16_t swap16(int16_t x){
return((((u_int16_t)x & 0x00ffU) << 8) |
(((u_int16_t)x & 0xff00U) >> 8));
}
#if BYTE_ORDER == LITTLE_ENDIAN
static inline int32_t be32_to_cpu(int32_t x){
return(swap32(x));
}
static inline int16_t be16_to_cpu(int16_t x){
return(swap16(x));
}
static inline int32_t le32_to_cpu(int32_t x){
return(x);
}
static inline int16_t le16_to_cpu(int16_t x){
return(x);
}
#else
static inline int32_t be32_to_cpu(int32_t x){
return(x);
}
static inline int16_t be16_to_cpu(int16_t x){
return(x);
}
static inline int32_t le32_to_cpu(int32_t x){
return(swap32(x));
}
static inline int16_t le16_to_cpu(int16_t x){
return(swap16(x));
}
#endif
static inline int32_t cpu_to_be32(int32_t x){
return(be32_to_cpu(x));
}
static inline int32_t cpu_to_le32(int32_t x){
return(le32_to_cpu(x));
}
static inline int16_t cpu_to_be16(int16_t x){
return(be16_to_cpu(x));
}
static inline int16_t cpu_to_le16(int16_t x){
return(le16_to_cpu(x));
}
static inline char *copystring(const char *s){
if(s){
char *ret=malloc((strlen(s)+9)*sizeof(char)); /* +9 to get around a linux
libc 5 bug. below too */
strcpy(ret,s);
return(ret);
}
return(NULL);
}
static inline char *catstring(char *buff,const char *s){
if(s){
if(buff)
buff=realloc(buff,strlen(buff)+strlen(s)+9);
else
buff=calloc(strlen(s)+9,1);
strcat(buff,s);
}
return(buff);
}
void cderror(cdrom_drive_t *d, const char *s);
void cdmessage(cdrom_drive_t *d,const char *s);
void idperror(int messagedest,char **messages,const char *f, const char *s);
void idmessage(int messagedest,char **messages,const char *f, const char *s);

9
lib/driver/.cvsignore Normal file
View File

@@ -0,0 +1,9 @@
.deps
.libs
Makefile
Makefile.in
*.o
*.lo
*.la
*.la.ver

View File

@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1 2004/06/20 15:35:31 rocky Exp $
# $Id: Makefile,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein
# This program is free software; you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd.c,v 1.42 2004/10/26 07:34:41 rocky Exp $
$Id: freebsd.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd.c,v 1.42 2004/10/26 07:34:41 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include "freebsd.h"

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd.h,v 1.21 2004/07/31 09:26:31 rocky Exp $
$Id: freebsd.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd_cam.c,v 1.31 2004/08/07 09:42:34 rocky Exp $
$Id: freebsd_cam.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.31 2004/08/07 09:42:34 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#ifdef HAVE_FREEBSD_CDROM

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd_ioctl.c,v 1.12 2004/08/10 02:29:46 rocky Exp $
$Id: freebsd_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd_ioctl.c,v 1.12 2004/08/10 02:29:46 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#ifdef HAVE_FREEBSD_CDROM

View File

@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1 2004/06/20 15:35:31 rocky Exp $
# $Id: Makefile,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein
# This program is free software; you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
$Id: aspi32.c,v 1.53 2004/11/07 16:29:05 rocky Exp $
$Id: aspi32.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: aspi32.c,v 1.53 2004/11/07 16:29:05 rocky Exp $";
static const char _rcsid[] = "$Id: aspi32.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <cdio/cdio.h>
#include <cdio/sector.h>

View File

@@ -1,6 +1,6 @@
/* Win32 aspi specific */
/*
$Id: aspi32.h,v 1.13 2004/08/27 04:12:29 rocky Exp $
$Id: aspi32.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: win32.c,v 1.50 2004/10/31 17:43:30 rocky Exp $
$Id: win32.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: win32.c,v 1.50 2004/10/31 17:43:30 rocky Exp $";
static const char _rcsid[] = "$Id: win32.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <cdio/cdio.h>
#include <cdio/sector.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: win32.h,v 1.21 2004/08/10 03:44:56 rocky Exp $
$Id: win32.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: win32_ioctl.c,v 1.43 2004/11/07 06:36:53 rocky Exp $
$Id: win32_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.43 2004/11/07 06:36:53 rocky Exp $";
static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#ifdef HAVE_WIN32_CDROM

173
lib/driver/Makefile.am Normal file
View File

@@ -0,0 +1,173 @@
# $Id: Makefile.am,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
########################################################
# Things to make the libcdio library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libcdio_la_CURRENT := 3
libcdio_la_REVISION := 0
libcdio_la_AGE := 0
EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \
libcdio.sym
noinst_HEADERS = cdio_assert.h cdio_private.h portable.h
libcdio_sources = \
_cdio_aix.c \
_cdio_bsdi.c \
_cdio_generic.c \
_cdio_linux.c \
_cdio_osx.c \
_cdio_stdio.c \
_cdio_stdio.h \
_cdio_stream.c \
_cdio_stream.h \
_cdio_sunos.c \
cd_types.c \
cdio.c \
cdtext.c \
cdtext_private.h \
ds.c \
FreeBSD/freebsd.c \
FreeBSD/freebsd.h \
FreeBSD/freebsd_cam.c \
FreeBSD/freebsd_ioctl.c \
generic.h \
image.h \
image/bincue.c \
image/cdrdao.c \
image_common.h \
image/nrg.c \
image/nrg.h \
MSWindows/aspi32.c \
MSWindows/aspi32.h \
MSWindows/win32_ioctl.c \
MSWindows/win32.c \
MSWindows/win32.h \
logging.c \
scsi_mmc.c \
scsi_mmc_private.h \
sector.c \
util.c
lib_LTLIBRARIES = libcdio.la
libcdio_la_SOURCES = $(libcdio_sources)
libcdio_la_ldflags = -version-info $(libcdio_la_CURRENT):$(libcdio_la_REVISION):$(libcdio_la_AGE)
INCLUDES = $(LIBCDIO_CFLAGS)
########################################################
# Things to version the symbols in the libraries
########################################################
# An explanation of the versioning problem from Nicolas Boullis and
# the versioned symbol solution he uses below...
#
# Currently, libvcdinfo uses the cdio_open function from libcdio.
# Let's imagine a program foobar that uses both the vcdinfo_open
# function from libvcdinfo and the cdio_open function from libcdio.
# Currently, libcdio has SONAME libcdio.so.0, libvcdinfo has SONAME
# libvcdinfo.so.0 and requires libcdio.so.0, and foobar requires both
# libvcdinfo.so.0 and libcdio.so.0. Everything looks fine.
#
# Now, for some reason, you decide to change the cdio_open function.
# That's your right, but you have to bump the CURRENT version and (if I
# understand it correctly, athough this is not that clear in libtool's
# documentation) set the AGE to 0. Anyway, this bumps the SONAME, which is
# sane since the interface changes incompatibly.
# Now, you have a new libcdio with SONAME libcdio.so.1. But libvcdinfo and
# foobar still require libcdio.so.0. Everything is still fine.
# Now, after some minor changes, the author of foobar recompiles foobar.
# Then, foobar now requires libvcdinfo.so.0 and libcdio.so.1. And foobar
# now segfaults...
# What is happening? When you run foobar, if brings both libvcdinfo.so.0
# and libcdio.so.1, but libvcdinfo.so.0 also brings libcdio.so.0. So you
# have both libcdio.so.0 and libcdio.so.1 that bring their symbols to the
# global namespace. Hence, you have to incompatible versions of the
# cdio_open function in the name space. When foobar calls cdio_open, it
# may choose the wrong function, and segfaults...
# With versioned symbols, the cdio_open function from libcdio.so.0 may be
# known as (something that looks like) cdio_open@@CDIO_0. An the cdio_open
# function from libcdio.so.1 as cdio_open@@CDIO_1. Both versions of
# libcdio would still be brought in by the most recent foobar, but foobar
# (and libvcdinfo) know which versioned function to use and then use the
# good one.
# This is some simple versioning where every symbol is versioned with
# something that looks like the SONAME of the library. More complex (and
# better) versioning is possible; it is for example what is used by glibc.
# But good complex versioning is something that requires much more
# work...
# The below is a impliments symbol versioning. First of all, I
# compute MAJOR as CURENT - AGE; that is what is used within libtool
# (at least on GNU/Linux systems) for the number in the SONAME. The
# nm command gives the list of symbols known in each of the object
# files that will be part of the shared library. And the sed command
# extracts from this list those symbols that will be shared. (This sed
# command comes from libtool.)
libcdio_la_MAJOR := $(shell expr $(libcdio_la_CURRENT) - $(libcdio_la_AGE))
if BUILD_VERSIONED_LIBS
libcdio_la_LDFLAGS = $(libcdio_la_ldflags) -Wl,--version-script=libcdio.la.ver
libcdio_la_DEPENDENCIES = libcdio.la.ver
libcdio.la.ver: $(libcdio_la_OBJECTS) $(srcdir)/libcdio.sym
echo 'CDIO_$(libcdio_la_MAJOR) { ' > $@
echo " global:" >> $@
nm $(patsubst %.lo,%.o,$(libcdio_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libcdio.sym; then echo " $${symbol};"; fi; done >> $@
echo " local:" >> $@
nm $(patsubst %.lo,%.o,$(libcdio_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libcdio.sym; then :; else echo " $${symbol};"; fi; done >> $@
echo '};' >> $@
else
libcdio_la_LDFLAGS = $(libcdio_la_ldflags)
endif
MOSTLYCLEANFILES = libcdio.la.ver

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_aix.c,v 1.1 2004/12/15 01:45:15 rocky Exp $
$Id: _cdio_aix.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -37,7 +37,7 @@
#ifdef HAVE_AIX_CDROM
static const char _rcsid[] = "$Id: _cdio_aix.c,v 1.1 2004/12/15 01:45:15 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_aix.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#ifdef HAVE_GLOB_H
#include <glob.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_bsdi.c,v 1.44 2004/11/20 12:50:26 rocky Exp $
$Id: _cdio_bsdi.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.44 2004/11/20 12:50:26 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <cdio/logging.h>
#include <cdio/sector.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_generic.c,v 1.29 2004/11/01 09:14:21 rocky Exp $
$Id: _cdio_generic.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -25,7 +25,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.29 2004/11/01 09:14:21 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_linux.c,v 1.101 2004/12/04 11:50:40 rocky Exp $
$Id: _cdio_linux.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.101 2004/12/04 11:50:40 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <string.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_osx.c,v 1.70 2004/10/26 07:34:41 rocky Exp $
$Id: _cdio_osx.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
from vcdimager code:
@@ -34,7 +34,7 @@
#include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.70 2004/10/26 07:34:41 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include <cdio/logging.h>
#include <cdio/sector.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_stdio.c,v 1.8 2004/06/19 19:15:15 rocky Exp $
$Id: _cdio_stdio.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -39,7 +39,7 @@
#include "_cdio_stream.h"
#include "_cdio_stdio.h"
static const char _rcsid[] = "$Id: _cdio_stdio.c,v 1.8 2004/06/19 19:15:15 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_stdio.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#define CDIO_STDIO_BUFSIZE (128*1024)

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_stdio.h,v 1.3 2004/02/07 18:53:02 rocky Exp $
$Id: _cdio_stdio.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_stream.c,v 1.10 2004/10/24 23:42:39 rocky Exp $
$Id: _cdio_stream.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
@@ -34,7 +34,7 @@
#include <cdio/util.h>
#include "_cdio_stream.h"
static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.10 2004/10/24 23:42:39 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
/*
* DataSource implementations

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_stream.h,v 1.8 2004/02/07 18:53:02 rocky Exp $
$Id: _cdio_stream.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_sunos.c,v 1.80 2004/12/06 05:30:43 rocky Exp $
$Id: _cdio_sunos.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -38,7 +38,7 @@
#ifdef HAVE_SOLARIS_CDROM
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.80 2004/12/06 05:30:43 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#ifdef HAVE_GLOB_H
#include <glob.h>

View File

@@ -1,5 +1,5 @@
/*
$Id: cd_types.c,v 1.10 2004/06/23 09:28:02 rocky Exp $
$Id: cd_types.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio.c,v 1.78 2004/12/17 04:50:46 rocky Exp $
$Id: cdio.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -39,7 +39,7 @@
#include <cdio/logging.h>
#include "cdio_private.h"
static const char _rcsid[] = "$Id: cdio.c,v 1.78 2004/12/17 04:50:46 rocky Exp $";
static const char _rcsid[] = "$Id: cdio.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
const char *track_format2str[6] =

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio_assert.h,v 1.4 2003/09/18 13:40:54 rocky Exp $
$Id: cdio_assert.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio_private.h,v 1.42 2004/09/03 23:20:11 rocky Exp $
$Id: cdio_private.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: cdtext.c,v 1.10 2004/11/08 04:13:27 rocky Exp $
$Id: cdtext.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
toc reading routine adapted from cuetools

View File

@@ -1,5 +1,5 @@
/*
$Id: cdtext_private.h,v 1.6 2004/10/28 03:50:32 rocky Exp $
$Id: cdtext_private.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: ds.c,v 1.4 2004/10/09 03:20:28 rocky Exp $
$Id: ds.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
@@ -30,7 +30,7 @@
#include <cdio/types.h>
#include "cdio_assert.h"
static const char _rcsid[] = "$Id: ds.c,v 1.4 2004/10/09 03:20:28 rocky Exp $";
static const char _rcsid[] = "$Id: ds.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
struct _CdioList
{

View File

@@ -1,5 +1,5 @@
/*
$Id: generic.h,v 1.3 2004/10/24 23:42:39 rocky Exp $
$Id: generic.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: image.h,v 1.3 2004/07/11 14:25:07 rocky Exp $
$Id: image.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1 2004/06/20 15:35:31 rocky Exp $
# $Id: Makefile,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein
# This program is free software; you can redistribute it and/or modify

View File

@@ -1,5 +1,5 @@
/*
$Id: bincue.c,v 1.47 2004/11/07 21:13:10 rocky Exp $
$Id: bincue.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -26,7 +26,7 @@
(*.cue).
*/
static const char _rcsid[] = "$Id: bincue.c,v 1.47 2004/11/07 21:13:10 rocky Exp $";
static const char _rcsid[] = "$Id: bincue.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include "image.h"
#include "cdio_assert.h"

View File

@@ -1,5 +1,5 @@
/*
$Id: cdrdao.c,v 1.30 2004/11/07 21:13:10 rocky Exp $
$Id: cdrdao.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
toc reading routine adapted from cuetools
@@ -25,7 +25,7 @@
(*.cue).
*/
static const char _rcsid[] = "$Id: cdrdao.c,v 1.30 2004/11/07 21:13:10 rocky Exp $";
static const char _rcsid[] = "$Id: cdrdao.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
#include "image.h"
#include "cdio_assert.h"

View File

@@ -1,5 +1,5 @@
/*
$Id: nrg.c,v 1.44 2004/12/17 04:57:14 rocky Exp $
$Id: nrg.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -46,7 +46,7 @@
#include "_cdio_stdio.h"
#include "nrg.h"
static const char _rcsid[] = "$Id: nrg.c,v 1.44 2004/12/17 04:57:14 rocky Exp $";
static const char _rcsid[] = "$Id: nrg.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
/* reader */

View File

@@ -1,5 +1,5 @@
/*
$Id: nrg.h,v 1.3 2004/07/09 02:46:42 rocky Exp $
$Id: nrg.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org>

View File

@@ -1,5 +1,5 @@
/*
$Id: image_common.h,v 1.17 2004/10/09 03:20:28 rocky Exp $
$Id: image_common.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: logging.c,v 1.7 2004/10/31 14:55:35 rocky Exp $
$Id: logging.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -31,7 +31,7 @@
#include "cdio_assert.h"
#include "portable.h"
static const char _rcsid[] = "$Id: logging.c,v 1.7 2004/10/31 14:55:35 rocky Exp $";
static const char _rcsid[] = "$Id: logging.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
cdio_log_level_t cdio_loglevel_default = CDIO_LOG_WARN;

View File

@@ -1,5 +1,5 @@
/*
$Id: portable.h,v 1.4 2004/11/07 21:13:10 rocky Exp $
$Id: portable.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) Rocky Bernstein <rocky@panix.com>

View File

@@ -1,6 +1,6 @@
/* Common SCSI Multimedia Command (MMC) routines.
$Id: scsi_mmc.c,v 1.32 2004/12/06 04:47:57 rocky Exp $
$Id: scsi_mmc.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -93,8 +93,11 @@ scsi_mmc_get_drive_cap_buf(const uint8_t *p,
if (p[2] & 0x02) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_RW;
if (p[2] & 0x08) *p_read_cap |= CDIO_DRIVE_CAP_READ_DVD_ROM;
if (p[4] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_AUDIO;
if (p[4] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM1;
if (p[4] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM2;
if (p[5] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_DA;
if (p[5] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_C2_ERRS;
if (p[5] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_ISRC;
/* Writer */
if (p[3] & 0x01) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_R;
@@ -154,13 +157,66 @@ scsi_mmc_run_cmd( const CdIo *p_cdio, unsigned int i_timeout_ms,
#define DEFAULT_TIMEOUT_MS 6000
int
scsi_mmc_get_blocksize_private ( const void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd)
{
int i_status = 0;
scsi_mmc_cdb_t cdb = {{0, }};
struct
{
uint8_t reserved1;
uint8_t medium;
uint8_t reserved2;
uint8_t block_desc_length;
uint8_t density;
uint8_t number_of_blocks_hi;
uint8_t number_of_blocks_med;
uint8_t number_of_blocks_lo;
uint8_t reserved3;
uint8_t block_length_hi;
uint8_t block_length_med;
uint8_t block_length_lo;
} mh;
uint8_t *p = &mh.block_length_med;
if ( ! p_env || ! run_scsi_mmc_cmd )
return -2;
memset (&mh, 0, sizeof (mh));
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SENSE);
cdb.field[1] = 0x3F&1;
cdb.field[4] = 12;
i_status = run_scsi_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, sizeof(mh), &mh);
if (0 != i_status) return -2;
return CDIO_MMC_GET_LEN16(p);
}
int
scsi_mmc_get_blocksize ( const CdIo *p_cdio)
{
if ( ! p_cdio ) return -2;
return
scsi_mmc_get_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd);
}
/*!
* Eject using SCSI MMC commands. Return 0 if successful.
*/
int
scsi_mmc_eject_media( const CdIo *p_cdio )
{
int i_status;
int i_status = 0;
scsi_mmc_cdb_t cdb = {{0, }};
uint8_t buf[1];
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd;
@@ -175,8 +231,7 @@ scsi_mmc_eject_media( const CdIo *p_cdio )
i_status = run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
if (0 != i_status) return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 1;
@@ -228,7 +283,7 @@ scsi_mmc_read_sectors ( const CdIo *p_cdio, void *p_buf, lba_t lba,
int
scsi_mmc_set_blocksize_private ( const void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int bsize)
unsigned int i_bsize)
{
scsi_mmc_cdb_t cdb = {{0, }};
@@ -253,9 +308,9 @@ scsi_mmc_set_blocksize_private ( const void *p_env,
memset (&mh, 0, sizeof (mh));
mh.block_desc_length = 0x08;
mh.block_length_hi = (bsize >> 16) & 0xff;
mh.block_length_med = (bsize >> 8) & 0xff;
mh.block_length_lo = (bsize >> 0) & 0xff;
mh.block_length_hi = (i_bsize >> 16) & 0xff;
mh.block_length_med = (i_bsize >> 8) & 0xff;
mh.block_length_lo = (i_bsize >> 0) & 0xff;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6);
@@ -268,12 +323,12 @@ scsi_mmc_set_blocksize_private ( const void *p_env,
}
int
scsi_mmc_set_blocksize ( const CdIo *cdio, unsigned int bsize)
scsi_mmc_set_blocksize ( const CdIo *p_cdio, unsigned int i_bsize)
{
if ( ! cdio ) return -2;
if ( ! p_cdio ) return -2;
return
scsi_mmc_set_blocksize_private (cdio->env, cdio->op.run_scsi_mmc_cmd,
bsize);
scsi_mmc_set_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd,
i_bsize);
}

View File

@@ -1,6 +1,6 @@
/* private MMC helper routines.
$Id: scsi_mmc_private.h,v 1.9 2004/07/31 07:43:26 rocky Exp $
$Id: scsi_mmc_private.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -55,9 +55,8 @@ scsi_mmc_get_dvd_struct_physical_private ( void *p_env, const
int
scsi_mmc_set_blocksize_private ( const void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int bsize);
scsi_mmc_get_blocksize_private ( const void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd);
char *scsi_mmc_get_mcn_private ( void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd
@@ -99,7 +98,8 @@ scsi_mmc_get_drive_cap_generic (const void *p_user_data,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
int
scsi_mmc_set_blocksize_private ( const void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int i_bsize);

View File

@@ -1,5 +1,5 @@
/*
$Id: sector.c,v 1.15 2004/11/18 01:56:09 rocky Exp $
$Id: sector.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
@@ -35,7 +35,7 @@
#include <ctype.h>
static const char _rcsid[] = "$Id: sector.c,v 1.15 2004/11/18 01:56:09 rocky Exp $";
static const char _rcsid[] = "$Id: sector.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
lba_t
cdio_lba_to_lsn (lba_t lba)

View File

@@ -1,5 +1,5 @@
/*
$Id: util.c,v 1.6 2004/11/15 01:34:09 rocky Exp $
$Id: util.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -36,7 +36,7 @@
#include <cdio/types.h>
#include <cdio/util.h>
static const char _rcsid[] = "$Id: util.c,v 1.6 2004/11/15 01:34:09 rocky Exp $";
static const char _rcsid[] = "$Id: util.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
size_t
_cdio_strlenv(char **str_array)

9
lib/iso9660/.cvsignore Normal file
View File

@@ -0,0 +1,9 @@
.deps
.libs
Makefile
Makefile.in
*.o
*.lo
*.la
*.la.ver

141
lib/iso9660/Makefile.am Normal file
View File

@@ -0,0 +1,141 @@
# $Id: Makefile.am,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
########################################################
# Things to make the libiso9660 library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libiso9660_la_CURRENT := 3
libiso9660_la_REVISION := 0
libiso9660_la_AGE := 0
EXTRA_DIST = libiso9660.sym
noinst_HEADERS = iso9660_private.h
lib_LTLIBRARIES = libiso9660.la
libiso9660_la_SOURCES = \
iso9660.c \
iso9660_private.h \
iso9660_fs.c \
xa.c
libiso9660_la_LIBADD = @LIBCDIO_LIBS@
libiso9660_la_ldflags = -version-info $(libiso9660_la_CURRENT):$(libiso9660_la_REVISION):$(libiso9660_la_AGE)
INCLUDES = $(LIBCDIO_CFLAGS)
########################################################
# Things to version the symbols in the libraries
########################################################
# An explanation of the versioning problem from Nicolas Boullis and
# the versioned symbol solution he uses below...
#
# Currently, libvcdinfo uses the cdio_open function from libcdio.
# Let's imagine a program foobar that uses both the vcdinfo_open
# function from libvcdinfo and the cdio_open function from libcdio.
# Currently, libcdio has SONAME libcdio.so.0, libvcdinfo has SONAME
# libvcdinfo.so.0 and requires libcdio.so.0, and foobar requires both
# libvcdinfo.so.0 and libcdio.so.0. Everything looks fine.
#
# Now, for some reason, you decide to change the cdio_open function.
# That's your right, but you have to bump the CURRENT version and (if I
# understand it correctly, athough this is not that clear in libtool's
# documentation) set the AGE to 0. Anyway, this bumps the SONAME, which is
# sane since the interface changes incompatibly.
# Now, you have a new libcdio with SONAME libcdio.so.1. But libvcdinfo and
# foobar still require libcdio.so.0. Everything is still fine.
# Now, after some minor changes, the author of foobar recompiles foobar.
# Then, foobar now requires libvcdinfo.so.0 and libcdio.so.1. And foobar
# now segfaults...
# What is happening? When you run foobar, if brings both libvcdinfo.so.0
# and libcdio.so.1, but libvcdinfo.so.0 also brings libcdio.so.0. So you
# have both libcdio.so.0 and libcdio.so.1 that bring their symbols to the
# global namespace. Hence, you have to incompatible versions of the
# cdio_open function in the name space. When foobar calls cdio_open, it
# may choose the wrong function, and segfaults...
# With versioned symbols, the cdio_open function from libcdio.so.0 may be
# known as (something that looks like) cdio_open@@CDIO_0. An the cdio_open
# function from libcdio.so.1 as cdio_open@@CDIO_1. Both versions of
# libcdio would still be brought in by the most recent foobar, but foobar
# (and libvcdinfo) know which versioned function to use and then use the
# good one.
# This is some simple versioning where every symbol is versioned with
# something that looks like the SONAME of the library. More complex (and
# better) versioning is possible; it is for example what is used by glibc.
# But good complex versioning is something that requires much more
# work...
# The below is a impliments symbol versioning. First of all, I
# compute MAJOR as CURENT - AGE; that is what is used within libtool
# (at least on GNU/Linux systems) for the number in the SONAME. The
# nm command gives the list of symbols known in each of the object
# files that will be part of the shared library. And the sed command
# extracts from this list those symbols that will be shared. (This sed
# command comes from libtool.)
libiso9660_la_MAJOR := $(shell expr $(libiso9660_la_CURRENT) - $(libiso9660_la_AGE))
if BUILD_VERSIONED_LIBS
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags) -Wl,--version-script=libiso9660.la.ver
libiso9660_la_DEPENDENCIES = @LIBCDIO_LIBS@ libiso9660.la.ver
libiso9660.la.ver: $(libiso9660_la_OBJECTS) $(srcdir)/libiso9660.sym
echo 'ISO9660_$(libiso9660_la_MAJOR) {' > $@
echo " global:" >> $@
nm $(patsubst %.lo,%.o,$(libiso9660_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then echo " $${symbol};"; fi; done >> $@
echo " local:" >> $@
nm $(patsubst %.lo,%.o,$(libiso9660_la_OBJECTS)) | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then :; else echo " $${symbol};"; fi; done >> $@
echo '};' >> $@
MOSTLYCLEANFILES = libiso9660.la.ver
else
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags)
libiso9660_la_DEPENDENCIES = @LIBCDIO_LIBS@
endif

View File

@@ -1,5 +1,5 @@
/*
$Id: iso9660.c,v 1.25 2004/11/21 22:32:03 rocky Exp $
$Id: iso9660.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -37,7 +37,7 @@
#include <stdio.h>
#endif
static const char _rcsid[] = "$Id: iso9660.c,v 1.25 2004/11/21 22:32:03 rocky Exp $";
static const char _rcsid[] = "$Id: iso9660.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
/* some parameters... */
#define SYSTEM_ID "CD-RTOS CD-BRIDGE"

View File

@@ -1,5 +1,5 @@
/*
$Id: iso9660_fs.c,v 1.42 2004/11/06 17:50:05 rocky Exp $
$Id: iso9660_fs.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -51,7 +51,7 @@
#include <stdio.h>
static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.42 2004/11/06 17:50:05 rocky Exp $";
static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
/* Implementation of iso9660_t type */
struct _iso9660 {

View File

@@ -1,5 +1,5 @@
/*
$Id: iso9660_private.h,v 1.8 2004/06/02 07:44:02 rocky Exp $
$Id: iso9660_private.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>

View File

@@ -1,5 +1,5 @@
/*
$Id: xa.c,v 1.5 2004/10/22 01:13:38 rocky Exp $
$Id: xa.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>

8
lib/paranoia/.cvsignore Normal file
View File

@@ -0,0 +1,8 @@
.deps
.libs
Makefile
Makefile.in
*.o
*.lo
*.la
*.la.ver

77
lib/paranoia/Makefile.am Normal file
View File

@@ -0,0 +1,77 @@
# $Id: Makefile.am,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
########################################################
# Things to make the libcdio_paranoia library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libcdio_paranoia_la_CURRENT := 0
libcdio_paranoia_la_REVISION := 0
libcdio_paranoia_la_AGE := 0
noinst_HEADERS = gap.h isort.h overlap.h p_block.h
libcdio_paranoia_sources = gap.c isort.c overlap.c overlap.h \
p_block.c paranoia.c
lib_LTLIBRARIES = libcdio_paranoia.la
libcdio_paranoia_la_SOURCES = $(libcdio_paranoia_sources)
libcdio_paranoia_la_ldflags = -version-info $(libcdio_paranoia_la_CURRENT):$(libcdio_paranoia_la_REVISION):$(libcdio_paranoia_la_AGE)
libcdio_paranoia_la_LDFLAGS = $(libcdio_paranoia_la_ldflags)
INCLUDES = $(LIBCDIO_CFLAGS)
FLAGS=@LIBCDIO_CFLAGS@ @TYPESIZES@ @CFLAGS@ -I.. -I../..
OPT=$(FLAGS)
DEBUG=$(FLAGS)
## SUFFIXES = .t
## TFILES = isort.t gap.t p_block.t paranoia.t
##test: $(TFILES)
##.c.t:
## $(CC) -g -DTEST $(DEBUG) -o $@ $< $(LIBS)
## $@
##debug:
## $(MAKE) libcdio_paranoia.a CFLAGS="$(DEBUG)"
LIBS = $(LIBCDIO_LIBS) $(LIBCDIO_CDDA_LIBS)

222
lib/paranoia/gap.c Normal file
View File

@@ -0,0 +1,222 @@
/*
$Id: gap.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/***
* Gap analysis support code for paranoia
*
***/
#include "config.h"
#include "p_block.h"
#include <cdio/paranoia.h>
#include "gap.h"
#include <string.h>
/**** Gap analysis code ***************************************************/
long int
i_paranoia_overlap_r(int16_t *buffA,int16_t *buffB,
long offsetA, long offsetB)
{
long beginA=offsetA;
long beginB=offsetB;
for( ; beginA>=0 && beginB>=0; beginA--,beginB-- )
if (buffA[beginA] != buffB[beginB]) break;
beginA++;
beginB++;
return(offsetA-beginA);
}
long int
i_paranoia_overlap_f(int16_t *buffA,int16_t *buffB,
long offsetA, long offsetB,
long sizeA,long sizeB)
{
long endA=offsetA;
long endB=offsetB;
for(;endA<sizeA && endB<sizeB;endA++,endB++)
if(buffA[endA]!=buffB[endB])break;
return(endA-offsetA);
}
int
i_stutter_or_gap(int16_t *A, int16_t *B,long offA, long offB, long int gap)
{
long a1=offA;
long b1=offB;
if(a1<0){
b1-=a1;
gap+=a1;
a1=0;
}
return(memcmp(A+a1,B+b1,gap*2));
}
/* riftv is the first value into the rift -> or <- */
void
i_analyze_rift_f(int16_t *A,int16_t *B,
long sizeA, long sizeB,
long aoffset, long boffset,
long *matchA,long *matchB,long *matchC)
{
long apast=sizeA-aoffset;
long bpast=sizeB-boffset;
long i;
*matchA=0, *matchB=0, *matchC=0;
/* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and
(c) AB->AB. */
for(i=0;;i++){
if(i<bpast) /* A */
if(i_paranoia_overlap_f(A,B,aoffset,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
*matchA=i;
break;
}
if(i<apast){ /* B */
if(i_paranoia_overlap_f(A,B,aoffset+i,boffset,sizeA,sizeB)>=MIN_WORDS_RIFT){
*matchB=i;
break;
}
if(i<bpast) /* C */
if(i_paranoia_overlap_f(A,B,aoffset+i,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
*matchC=i;
break;
}
}else
if(i>=bpast)break;
}
if(*matchA==0 && *matchB==0 && *matchC==0)return;
if(*matchC)return;
if(*matchA){
if(i_stutter_or_gap(A,B,aoffset-*matchA,boffset,*matchA))
return;
*matchB=-*matchA; /* signify we need to remove n bytes from B */
*matchA=0;
return;
}else{
if(i_stutter_or_gap(B,A,boffset-*matchB,aoffset,*matchB))
return;
*matchA=-*matchB;
*matchB=0;
return;
}
}
/* riftv must be first even val of rift moving back */
void
i_analyze_rift_r(int16_t *A,int16_t *B,
long sizeA, long sizeB,
long aoffset, long boffset,
long *matchA,long *matchB,long *matchC)
{
long apast=aoffset+1;
long bpast=boffset+1;
long i;
*matchA=0, *matchB=0, *matchC=0;
/* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and
(c) AB->AB. */
for(i=0;;i++){
if(i<bpast) /* A */
if(i_paranoia_overlap_r(A,B,aoffset,boffset-i)>=MIN_WORDS_RIFT){
*matchA=i;
break;
}
if(i<apast){ /* B */
if(i_paranoia_overlap_r(A,B,aoffset-i,boffset)>=MIN_WORDS_RIFT){
*matchB=i;
break;
}
if(i<bpast) /* C */
if(i_paranoia_overlap_r(A,B,aoffset-i,boffset-i)>=MIN_WORDS_RIFT){
*matchC=i;
break;
}
}else
if(i>=bpast)break;
}
if(*matchA==0 && *matchB==0 && *matchC==0)return;
if(*matchC)return;
if(*matchA){
if(i_stutter_or_gap(A,B,aoffset+1,boffset-*matchA+1,*matchA))
return;
*matchB=-*matchA; /* signify we need to remove n bytes from B */
*matchA=0;
return;
}else{
if(i_stutter_or_gap(B,A,boffset+1,aoffset-*matchB+1,*matchB))
return;
*matchA=-*matchB;
*matchB=0;
return;
}
}
void
analyze_rift_silence_f(int16_t *A,int16_t *B,long sizeA,long sizeB,
long aoffset, long boffset,
long *matchA, long *matchB)
{
*matchA=-1;
*matchB=-1;
sizeA=min(sizeA,aoffset+MIN_WORDS_RIFT);
sizeB=min(sizeB,boffset+MIN_WORDS_RIFT);
aoffset++;
boffset++;
while(aoffset<sizeA){
if(A[aoffset]!=A[aoffset-1]){
*matchA=0;
break;
}
aoffset++;
}
while(boffset<sizeB){
if(B[boffset]!=B[boffset-1]){
*matchB=0;
break;
}
boffset++;
}
}

44
lib/paranoia/gap.h Normal file
View File

@@ -0,0 +1,44 @@
/*
$Id: gap.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _GAP_H_
#define _GAP_H_
extern long i_paranoia_overlap_r(int16_t *buffA,int16_t *buffB,
long offsetA, long offsetB);
extern long i_paranoia_overlap_f(int16_t *buffA,int16_t *buffB,
long offsetA, long offsetB,
long sizeA,long sizeB);
extern int i_stutter_or_gap(int16_t *A, int16_t *B,long offA, long offB,
long gap);
extern void i_analyze_rift_f(int16_t *A,int16_t *B,
long sizeA, long sizeB,
long aoffset, long boffset,
long *matchA,long *matchB,long *matchC);
extern void i_analyze_rift_r(int16_t *A,int16_t *B,
long sizeA, long sizeB,
long aoffset, long boffset,
long *matchA,long *matchB,long *matchC);
extern void analyze_rift_silence_f(int16_t *A,int16_t *B,long sizeA,long sizeB,
long aoffset, long boffset,
long *matchA, long *matchB);
#endif /*_GAP_H*/

132
lib/paranoia/isort.c Normal file
View File

@@ -0,0 +1,132 @@
/*
$Id: isort.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* sorted vector abstraction for paranoia */
/* Old isort got a bit complex. This re-constrains complexity to
give a go at speed through a more alpha-6-like mechanism. */
#include <stdlib.h>
#include <string.h>
#include "p_block.h"
#include "isort.h"
sort_info *sort_alloc(long size){
sort_info *ret=calloc(1,sizeof(sort_info));
ret->vector=NULL;
ret->sortbegin=-1;
ret->size=-1;
ret->maxsize=size;
ret->head=calloc(65536,sizeof(sort_link *));
ret->bucketusage=malloc(65536*sizeof(long));
ret->revindex=calloc(size,sizeof(sort_link));
ret->lastbucket=0;
return(ret);
}
void sort_unsortall(sort_info *i){
if(i->lastbucket>2000){ /* a guess */
memset(i->head,0,65536*sizeof(sort_link *));
}else{
long b;
for(b=0;b<i->lastbucket;b++)
i->head[i->bucketusage[b]]=NULL;
}
i->lastbucket=0;
i->sortbegin=-1;
}
void sort_free(sort_info *i){
free(i->revindex);
free(i->head);
free(i->bucketusage);
free(i);
}
static void sort_sort(sort_info *i,long sortlo,long sorthi){
long j;
for(j=sorthi-1;j>=sortlo;j--){
sort_link **hv=i->head+i->vector[j]+32768;
sort_link *l=i->revindex+j;
if(*hv==NULL){
i->bucketusage[i->lastbucket]=i->vector[j]+32768;
i->lastbucket++;
}
l->next=*hv;
*hv=l;
}
i->sortbegin=0;
}
/* size *must* be less than i->maxsize */
void sort_setup(sort_info *i,int16_t *vector,long *abspos,
long size,long sortlo,long sorthi){
if(i->sortbegin!=-1)sort_unsortall(i);
i->vector=vector;
i->size=size;
i->abspos=abspos;
i->lo=min(size,max(sortlo-*abspos,0));
i->hi=max(0,min(sorthi-*abspos,size));
}
sort_link *
sort_getmatch(sort_info *i,long post,long overlap,int value)
{
sort_link *ret;
if(i->sortbegin==-1)sort_sort(i,i->lo,i->hi);
/* Now we reuse lo and hi */
post=max(0,min(i->size,post));
i->val=value+32768;
i->lo=max(0,post-overlap); /* absolute position */
i->hi=min(i->size,post+overlap); /* absolute position */
ret=i->head[i->val];
while(ret){
if(ipos(i,ret)<i->lo){
ret=ret->next;
}else{
if(ipos(i,ret)>=i->hi)
ret=NULL;
break;
}
}
/*i->head[i->val]=ret;*/
return(ret);
}
sort_link *
sort_nextmatch(sort_info *i,sort_link *prev)
{
sort_link *ret=prev->next;
if(!ret || ipos(i,ret)>=i->hi)return(NULL);
return(ret);
}

65
lib/paranoia/isort.h Normal file
View File

@@ -0,0 +1,65 @@
/*
$Id: isort.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ISORT_H_
#define _ISORT_H_
typedef struct sort_link{
struct sort_link *next;
} sort_link;
typedef struct sort_info{
int16_t *vector; /* vector (storage doesn't belong to us) */
long *abspos; /* pointer for side effects */
long size; /* vector size */
long maxsize; /* maximum vector size */
long sortbegin; /* range of contiguous sorted area */
long lo,hi; /* current post, overlap range */
int val; /* ...and val */
/* sort structs */
sort_link **head; /* sort buckets (65536) */
long *bucketusage; /* of used buckets (65536) */
long lastbucket;
sort_link *revindex;
} sort_info;
extern sort_info *sort_alloc(long size);
extern void sort_unsortall(sort_info *i);
extern void sort_setup(sort_info *i,int16_t *vector,long *abspos,long size,
long sortlo, long sorthi);
extern void sort_free(sort_info *i);
extern sort_link *sort_getmatch(sort_info *i,long post,long overlap,int value);
extern sort_link *sort_nextmatch(sort_info *i,sort_link *prev);
#define is(i) (i->size)
#define ib(i) (*i->abspos)
#define ie(i) (i->size+*i->abspos)
#define iv(i) (i->vector)
#define ipos(i,l) (l-i->revindex)
#endif

210
lib/paranoia/overlap.c Normal file
View File

@@ -0,0 +1,210 @@
/*
$Id: overlap.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/***
*
* Statistic code and cache management for overlap settings
*
***/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cdio/paranoia.h>
#include "p_block.h"
#include "overlap.h"
#include "isort.h"
/**** Internal cache management *****************************************/
void
paranoia_resetcache(cdrom_paranoia_t *p)
{
c_block *c=c_first(p);
v_fragment *v;
while(c){
free_c_block(c);
c=c_first(p);
}
v=v_first(p);
while(v){
free_v_fragment(v);
v=v_first(p);
}
}
void
paranoia_resetall(cdrom_paranoia_t *p)
{
p->root.returnedlimit=0;
p->dyndrift=0;
p->root.lastsector=0;
if(p->root.vector){
i_cblock_destructor(p->root.vector);
p->root.vector=NULL;
}
paranoia_resetcache(p);
}
void
i_paranoia_trim(cdrom_paranoia_t *p, long int beginword, long int endword)
{
root_block *root=&(p->root);
if(root->vector!=NULL){
long target=beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
long rbegin=cb(root->vector);
long rend=ce(root->vector);
if(rbegin>beginword)
goto rootfree;
if(rbegin+MAX_SECTOR_OVERLAP*CD_FRAMEWORDS<beginword){
if(target+MIN_WORDS_OVERLAP>rend)
goto rootfree;
{
long int offset=target-rbegin;
c_removef(root->vector,offset);
}
}
{
c_block *c=c_first(p);
while(c){
c_block *next=c_next(c);
if(ce(c)<beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS)
free_c_block(c);
c=next;
}
}
}
return;
rootfree:
i_cblock_destructor(root->vector);
root->vector=NULL;
root->returnedlimit=-1;
root->lastsector=0;
}
/**** Statistical and heuristic[al? :-] management ************************/
void
offset_adjust_settings(cdrom_paranoia_t *p,
void(*callback)(long int, paranoia_cb_mode_t))
{
if(p->stage2.offpoints>=10){
/* drift: look at the average offset value. If it's over one
sector, frob it. We just want a little hysteresis [sp?]*/
long av=(p->stage2.offpoints?p->stage2.offaccum/p->stage2.offpoints:0);
if(abs(av)>p->dynoverlap/4){
av=(av/MIN_SECTOR_EPSILON)*MIN_SECTOR_EPSILON;
if(callback)(*callback)(ce(p->root.vector),PARANOIA_CB_DRIFT);
p->dyndrift+=av;
/* Adjust all the values in the cache otherwise we get a
(potentially unstable) feedback loop */
{
c_block *c=c_first(p);
v_fragment *v=v_first(p);
while(v && v->one){
/* safeguard beginning bounds case with a hammer */
if(fb(v)<av || cb(v->one)<av){
v->one=NULL;
}else{
fb(v)-=av;
}
v=v_next(v);
}
while(c){
long adj=min(av,cb(c));
c_set(c,cb(c)-adj);
c=c_next(c);
}
}
p->stage2.offaccum=0;
p->stage2.offmin=0;
p->stage2.offmax=0;
p->stage2.offpoints=0;
p->stage2.newpoints=0;
p->stage2.offdiff=0;
}
}
if(p->stage1.offpoints>=10){
/* dynoverlap: we arbitrarily set it to 4x the running difference
value, unless min/max are more */
p->dynoverlap=(p->stage1.offpoints?p->stage1.offdiff/
p->stage1.offpoints*3:CD_FRAMEWORDS);
if(p->dynoverlap<-p->stage1.offmin*1.5)
p->dynoverlap=-p->stage1.offmin*1.5;
if(p->dynoverlap<p->stage1.offmax*1.5)
p->dynoverlap=p->stage1.offmax*1.5;
if(p->dynoverlap<MIN_SECTOR_EPSILON)p->dynoverlap=MIN_SECTOR_EPSILON;
if(p->dynoverlap>MAX_SECTOR_OVERLAP*CD_FRAMEWORDS)
p->dynoverlap=MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
if(callback)(*callback)(p->dynoverlap,PARANOIA_CB_OVERLAP);
if(p->stage1.offpoints>600){ /* bit of a bug; this routine is
called too often due to the overlap
mesh alg we use in stage 1 */
p->stage1.offpoints/=1.2;
p->stage1.offaccum/=1.2;
p->stage1.offdiff/=1.2;
}
p->stage1.offmin=0;
p->stage1.offmax=0;
p->stage1.newpoints=0;
}
}
void
offset_add_value(cdrom_paranoia_t *p,offsets *o,long value,
void(*callback)(long int, paranoia_cb_mode_t))
{
if(o->offpoints!=-1){
o->offdiff+=abs(value);
o->offpoints++;
o->newpoints++;
o->offaccum+=value;
if(value<o->offmin)o->offmin=value;
if(value>o->offmax)o->offmax=value;
if(o->newpoints>=10)offset_adjust_settings(p,callback);
}
}

34
lib/paranoia/overlap.h Normal file
View File

@@ -0,0 +1,34 @@
/*
$Id: overlap.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _OVERLAP_H_
#define _OVERLAP_H_
extern void offset_add_value(cdrom_paranoia_t *p,offsets *o,long value,
void(*callback)(long int, paranoia_cb_mode_t));
extern void offset_clear_settings(offsets *o);
extern void offset_adjust_settings(cdrom_paranoia_t *p,
void(*callback)(long, paranoia_cb_mode_t));
extern void i_paranoia_trim(cdrom_paranoia_t *p,long beginword,long endword);
extern void paranoia_resetall(cdrom_paranoia_t *p);
extern void paranoia_resetcache(cdrom_paranoia_t *p);
#endif /*_OVERLAP_H_*/

402
lib/paranoia/p_block.c Normal file
View File

@@ -0,0 +1,402 @@
/*
$Id: p_block.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "p_block.h"
#include <cdio/cdda_interface.h>
#include <cdio/paranoia.h>
linked_list *new_list(void *(*newp)(void),void (*freep)(void *))
{
linked_list *ret=calloc(1,sizeof(linked_list));
ret->new_poly=newp;
ret->free_poly=freep;
return(ret);
}
linked_element *add_elem(linked_list *l,void *elem)
{
linked_element *ret=calloc(1,sizeof(linked_element));
ret->stamp=l->current++;
ret->ptr=elem;
ret->list=l;
if(l->head)
l->head->prev=ret;
else
l->tail=ret;
ret->next=l->head;
ret->prev=NULL;
l->head=ret;
l->active++;
return(ret);
}
linked_element *
new_elem(linked_list *list)
{
void *new=list->new_poly();
return(add_elem(list,new));
}
void
free_elem(linked_element *e,int free_ptr)
{
linked_list *l=e->list;
if(free_ptr)l->free_poly(e->ptr);
if(e==l->head)
l->head=e->next;
if(e==l->tail)
l->tail=e->prev;
if(e->prev)
e->prev->next=e->next;
if(e->next)
e->next->prev=e->prev;
l->active--;
free(e);
}
void
free_list(linked_list *list,int free_ptr)
{
while(list->head)
free_elem(list->head,free_ptr);
free(list);
}
void *get_elem(linked_element *e)
{
return(e->ptr);
}
linked_list *copy_list(linked_list *list)
{
linked_list *new=new_list(list->new_poly,list->free_poly);
linked_element *i=list->tail;
while(i){
add_elem(new,i->ptr);
i=i->prev;
}
return(new);
}
/**** C_block stuff ******************************************************/
static c_block *
i_cblock_constructor(cdrom_paranoia_t *p)
{
c_block *ret=calloc(1,sizeof(c_block));
return(ret);
}
void
i_cblock_destructor(c_block *c)
{
if(c){
if(c->vector)free(c->vector);
if(c->flags)free(c->flags);
c->e=NULL;
free(c);
}
}
c_block *
new_c_block(cdrom_paranoia_t *p)
{
linked_element *e=new_elem(p->cache);
c_block *c=e->ptr;
c->e=e;
c->p=p;
return(c);
}
void free_c_block(c_block *c)
{
/* also rid ourselves of v_fragments that reference this block */
v_fragment *v=v_first(c->p);
while(v){
v_fragment *next=v_next(v);
if(v->one==c)free_v_fragment(v);
v=next;
}
free_elem(c->e,1);
}
static v_fragment *
i_vfragment_constructor(void)
{
v_fragment *ret=calloc(1,sizeof(v_fragment));
return(ret);
}
static inline void
i_v_fragment_destructor(v_fragment *v)
{
free(v);
}
v_fragment *
new_v_fragment(cdrom_paranoia_t *p, c_block *one,
long int begin, long int end, int last)
{
linked_element *e=new_elem(p->fragments);
v_fragment *b=e->ptr;
b->e=e;
b->p=p;
b->one=one;
b->begin=begin;
b->vector=one->vector+begin-one->begin;
b->size=end-begin;
b->lastsector=last;
return(b);
}
void free_v_fragment(v_fragment *v)
{
free_elem(v->e,1);
}
c_block *
c_first(cdrom_paranoia_t *p)
{
if(p->cache->head)
return(p->cache->head->ptr);
return(NULL);
}
c_block *
c_last(cdrom_paranoia_t *p)
{
if(p->cache->tail)
return(p->cache->tail->ptr);
return(NULL);
}
c_block *
c_next(c_block *c)
{
if(c->e->next)
return(c->e->next->ptr);
return(NULL);
}
c_block *
c_prev(c_block *c)
{
if(c->e->prev)
return(c->e->prev->ptr);
return(NULL);
}
v_fragment *
v_first(cdrom_paranoia_t *p)
{
if(p->fragments->head){
return(p->fragments->head->ptr);
}
return(NULL);
}
v_fragment *
v_last(cdrom_paranoia_t *p)
{
if(p->fragments->tail)
return(p->fragments->tail->ptr);
return(NULL);
}
v_fragment *
v_next(v_fragment *v)
{
if(v->e->next)
return(v->e->next->ptr);
return(NULL);
}
v_fragment *
v_prev(v_fragment *v)
{
if(v->e->prev)
return(v->e->prev->ptr);
return(NULL);
}
void
recover_cache(cdrom_paranoia_t *p)
{
linked_list *l=p->cache;
/* Are we at/over our allowed cache size? */
while(l->active>p->cache_limit)
/* cull from the tail of the list */
free_c_block(c_last(p));
}
int16_t *
v_buffer(v_fragment *v)
{
if(!v->one)return(NULL);
if(!cv(v->one))return(NULL);
return(v->vector);
}
/* alloc a c_block not on a cache list */
c_block *
c_alloc(int16_t *vector,long begin,long size)
{
c_block *c=calloc(1,sizeof(c_block));
c->vector=vector;
c->begin=begin;
c->size=size;
return(c);
}
void c_set(c_block *v,long begin){
v->begin=begin;
}
/* pos here is vector position from zero */
void c_insert(c_block *v,long pos,int16_t *b,long size)
{
int vs=cs(v);
if(pos<0 || pos>vs)return;
if(v->vector)
v->vector=realloc(v->vector,sizeof(int16_t)*(size+vs));
else
v->vector=malloc(sizeof(int16_t)*size);
if(pos<vs)memmove(v->vector+pos+size,v->vector+pos,
(vs-pos)*sizeof(int16_t));
memcpy(v->vector+pos,b,size*sizeof(int16_t));
v->size+=size;
}
void c_remove(c_block *v,long cutpos,long cutsize)
{
int vs=cs(v);
if(cutpos<0 || cutpos>vs)return;
if(cutpos+cutsize>vs)cutsize=vs-cutpos;
if(cutsize<0)cutsize=vs-cutpos;
if(cutsize<1)return;
memmove(v->vector+cutpos,v->vector+cutpos+cutsize,
(vs-cutpos-cutsize)*sizeof(int16_t));
v->size-=cutsize;
}
void c_overwrite(c_block *v,long pos,int16_t *b,long size){
int vs=cs(v);
if(pos<0)return;
if(pos+size>vs)size=vs-pos;
memcpy(v->vector+pos,b,size*sizeof(int16_t));
}
void
c_append(c_block *v, int16_t *vector, long size)
{
int vs=cs(v);
/* update the vector */
if(v->vector)
v->vector=realloc(v->vector,sizeof(int16_t)*(size+vs));
else
v->vector=malloc(sizeof(int16_t)*size);
memcpy(v->vector+vs,vector,sizeof(int16_t)*size);
v->size+=size;
}
void c_removef(c_block *v, long cut){
c_remove(v,0,cut);
v->begin+=cut;
}
/**** Initialization *************************************************/
void
i_paranoia_firstlast(cdrom_paranoia_t *p)
{
int i;
cdrom_drive_t *d=p->d;
p->current_lastsector=-1;
for(i=cdda_sector_gettrack(d,p->cursor);i<cdda_tracks(d);i++)
if(!cdda_track_audiop(d,i))
p->current_lastsector=cdda_track_lastsector(d,i-1);
if(p->current_lastsector==-1)
p->current_lastsector=cdda_disc_lastsector(d);
p->current_firstsector=-1;
for(i=cdda_sector_gettrack(d,p->cursor);i>0;i--)
if(!cdda_track_audiop(d,i))
p->current_firstsector=cdda_track_firstsector(d,i+1);
if(p->current_firstsector==-1)
p->current_firstsector=cdda_disc_firstsector(d);
}
cdrom_paranoia_t *
paranoia_init(cdrom_drive_t *d)
{
cdrom_paranoia_t *p=calloc(1,sizeof(cdrom_paranoia_t));
p->cache=new_list((void *)&i_cblock_constructor,
(void *)&i_cblock_destructor);
p->fragments=new_list((void *)&i_vfragment_constructor,
(void *)&i_v_fragment_destructor);
p->readahead=150;
p->sortcache=sort_alloc(p->readahead*CD_FRAMEWORDS);
p->d=d;
p->dynoverlap=MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
p->cache_limit=JIGGLE_MODULO;
p->enable=PARANOIA_MODE_FULL;
p->cursor=cdda_disc_firstsector(d);
p->lastread=LONG_MAX;
/* One last one... in case data and audio tracks are mixed... */
i_paranoia_firstlast(p);
return(p);
}

208
lib/paranoia/p_block.h Normal file
View File

@@ -0,0 +1,208 @@
/*
$Id: p_block.h,v 1.1 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) by Monty (xiphmont@mit.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _P_BLOCK_H_
#define _P_BLOCK_H_
#include <cdio/paranoia.h>
#include <cdio/cdda_interface.h>
#define MIN_WORDS_OVERLAP 64 /* 16 bit words */
#define MIN_WORDS_SEARCH 64 /* 16 bit words */
#define MIN_WORDS_RIFT 16 /* 16 bit words */
#define MAX_SECTOR_OVERLAP 32 /* sectors */
#define MIN_SECTOR_EPSILON 128 /* words */
#define MIN_SECTOR_BACKUP 16 /* sectors */
#define JIGGLE_MODULO 15 /* sectors */
#define MIN_SILENCE_BOUNDARY 1024 /* 16 bit words */
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)<(y)?(y):(x))
#include "isort.h"
typedef struct linked_list{
/* linked list */
struct linked_element *head;
struct linked_element *tail;
void *(*new_poly)();
void (*free_poly)(void *poly);
long current;
long active;
} linked_list;
typedef struct linked_element{
void *ptr;
struct linked_element *prev;
struct linked_element *next;
struct linked_list *list;
int stamp;
} linked_element;
extern linked_list *new_list(void *(*new)(void),void (*free)(void *));
extern linked_element *new_elem(linked_list *list);
extern linked_element *add_elem(linked_list *list,void *elem);
extern void free_list(linked_list *list,int free_ptr); /* unlink or free */
extern void free_elem(linked_element *e,int free_ptr); /* unlink or free */
extern void *get_elem(linked_element *e);
extern linked_list *copy_list(linked_list *list); /* shallow; doesn't copy
contained structures */
typedef struct c_block{
/* The buffer */
int16_t *vector;
long begin;
long size;
/* auxiliary support structures */
unsigned char *flags; /* 1 known boundaries in read data
2 known blanked data
4 matched sample
8 reserved
16 reserved
32 reserved
64 reserved
128 reserved
*/
/* end of session cases */
long lastsector;
cdrom_paranoia_t *p;
struct linked_element *e;
} c_block;
extern void free_c_block(c_block *c);
extern void i_cblock_destructor(c_block *c);
extern c_block *new_c_block(cdrom_paranoia_t *p);
typedef struct v_fragment{
c_block *one;
long begin;
long size;
int16_t *vector;
/* end of session cases */
long lastsector;
/* linked list */
cdrom_paranoia_t *p;
struct linked_element *e;
} v_fragment;
extern void free_v_fragment(v_fragment *c);
extern v_fragment *new_v_fragment(cdrom_paranoia_t *p, c_block *one,
long int begin, long int end,
int lastsector);
extern int16_t *v_buffer(v_fragment *v);
extern c_block *c_first(cdrom_paranoia_t *p);
extern c_block *c_last(cdrom_paranoia_t *p);
extern c_block *c_next(c_block *c);
extern c_block *c_prev(c_block *c);
extern v_fragment *v_first(cdrom_paranoia_t *p);
extern v_fragment *v_last(cdrom_paranoia_t *p);
extern v_fragment *v_next(v_fragment *v);
extern v_fragment *v_prev(v_fragment *v);
typedef struct root_block{
long returnedlimit;
long lastsector;
cdrom_paranoia_t *p;
c_block *vector; /* doesn't use any sorting */
int silenceflag;
long silencebegin;
} root_block;
typedef struct offsets{
long offpoints;
long newpoints;
long offaccum;
long offdiff;
long offmin;
long offmax;
} offsets;
struct cdrom_paranoia_s {
cdrom_drive_t *d;
root_block root; /* verified/reconstructed cached data */
linked_list *cache; /* our data as read from the cdrom */
long int cache_limit;
linked_list *fragments; /* fragments of blocks that have been 'verified' */
sort_info *sortcache;
int readahead; /* sectors of readahead in each readop */
int jitter;
long lastread;
paranoia_cb_mode_t enable;
long int cursor;
long int current_lastsector;
long int current_firstsector;
/* statistics for drift/overlap */
struct offsets stage1;
struct offsets stage2;
long dynoverlap;
long dyndrift;
/* statistics for verification */
};
extern c_block *c_alloc(int16_t *vector,long begin,long size);
extern void c_set(c_block *v,long begin);
extern void c_insert(c_block *v,long pos,int16_t *b,long size);
extern void c_remove(c_block *v,long cutpos,long cutsize);
extern void c_overwrite(c_block *v,long pos,int16_t *b,long size);
extern void c_append(c_block *v, int16_t *vector, long size);
extern void c_removef(c_block *v, long cut);
#define ce(v) (v->begin+v->size)
#define cb(v) (v->begin)
#define cs(v) (v->size)
/* pos here is vector position from zero */
extern void recover_cache(cdrom_paranoia_t *p);
extern void i_paranoia_firstlast(cdrom_paranoia_t *p);
#define cv(c) (c->vector)
#define fe(f) (f->begin+f->size)
#define fb(f) (f->begin)
#define fs(f) (f->size)
#define fv(f) (v_buffer(f))
#define CDP_COMPILE
#endif /*_P_BLOCK_H_*/

1399
lib/paranoia/paranoia.c Normal file

File diff suppressed because it is too large Load Diff

11
libcdio_cdda.pc.in Normal file
View File

@@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Description: Portable CD-ROM I/O library
Version: @PACKAGE_VERSION@
#Requires: glib-2.0
Libs: -L${libdir} -lcdda_interface
Cflags: -I${includedir}

11
libcdio_paranoia.pc.in Normal file
View File

@@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Description: Portable CD-ROM I/O library
Version: @PACKAGE_VERSION@
#Requires: glib-2.0
Libs: -L${libdir} -lcdio_paranoia -lcdda_interface
Cflags: -I${includedir}

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.26 2004/10/26 08:32:29 rocky Exp $
# $Id: Makefile.am,v 1.27 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
#
@@ -19,6 +19,8 @@
####################################################
# Things to make the sample/test programs
####################################################
SUBDIRS = cd-paranoia
CDDB_LIBS=@CDDB_LIBS@
if MAINTAINER_MODE

View File

@@ -1,5 +1,5 @@
/*
$Id: cd-info.c,v 1.101 2004/12/04 11:44:16 rocky Exp $
$Id: cd-info.c,v 1.102 2004/12/18 17:29:32 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org>
@@ -47,7 +47,6 @@
#include <cdio/scsi_mmc.h>
#include "cdio_assert.h"
#include "iso9660_private.h"
#include <fcntl.h>
#ifdef __linux__
@@ -1060,9 +1059,13 @@ main(int argc, const char *argv[])
psz_msf = cdio_msf_to_str(&msf);
if (i == CDIO_CDROM_LEADOUT_TRACK) {
if (!opts.no_tracks)
printf("%3d: %8s %06lu leadout\n", (int) i, psz_msf,
(long unsigned int) cdio_msf_to_lsn(&msf));
if (!opts.no_tracks) {
lsn_t lsn= cdio_msf_to_lsn(&msf);
long unsigned int i_mb = ( lsn * CDIO_CD_FRAMESIZE_RAW ) /
(1024 * 1024);
printf( "%3d: %8s %06lu leadout (%lu MB)\n", (int) i, psz_msf,
(long unsigned int) lsn, i_mb );
}
free(psz_msf);
break;
} else if (!opts.no_tracks) {

View File

@@ -0,0 +1,6 @@
.deps
.libs
Makefile
Makefile.in
*.o
cd-paranoia

View File

@@ -0,0 +1,34 @@
# $Id: Makefile.am,v 1.1 2004/12/18 17:29:32 rocky Exp $
#
# Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
# Copyright (C) 1998 Monty xiphmont@mit.edu
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
###############################################################################
cd_paranoia_SOURCES = cd-paranoia.c \
buffering_write.c buffering_write.h \
header.c header.h \
report.c report.h
cd_paranoia_LDADD = $(LIBCDIO_LIBS) $(LIBCDIO_CDDA_LIBS) $(LIBCDIO_PARANOIA_LIBS)
bin_PROGRAMS = cd-paranoia$(EXEEXT)
man_MANS = cd-paranoia.1 cd-paranoia.1.jp
EXTRA_DIST = $(man_MANS)
INCLUDES = -I$(top_srcdir) $(LIBCDIO_CFLAGS)

View File

@@ -0,0 +1,73 @@
/* Eliminate teeny little writes. patch submitted by
Rob Ross <rbross@parl.ces.clemson.edu> --Monty 19991008 */
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#define OUTBUFSZ 32*1024
#include "utils.h"
#include "buffering_write.h"
/* GLOBALS FOR BUFFERING CALLS */
static int bw_fd = -1;
static long bw_pos = 0;
static char bw_outbuf[OUTBUFSZ];
/* buffering_write() - buffers data to a specified size before writing.
*
* Restrictions:
* - MUST CALL BUFFERING_CLOSE() WHEN FINISHED!!!
*
*/
long buffering_write(int fd, char *buffer, long num)
{
if (fd != bw_fd) {
/* clean up after buffering for some other file */
if (bw_fd >= 0 && bw_pos > 0) {
if (blocking_write(bw_fd, bw_outbuf, bw_pos)) {
perror("write (in buffering_write, flushing)");
}
}
bw_fd = fd;
bw_pos = 0;
}
if (bw_pos + num > OUTBUFSZ) {
/* fill our buffer first, then write, then modify buffer and num */
memcpy(&bw_outbuf[bw_pos], buffer, OUTBUFSZ - bw_pos);
if (blocking_write(fd, bw_outbuf, OUTBUFSZ)) {
perror("write (in buffering_write, full buffer)");
return(-1);
}
num -= (OUTBUFSZ - bw_pos);
buffer += (OUTBUFSZ - bw_pos);
bw_pos = 0;
}
/* save data */
memcpy(&bw_outbuf[bw_pos], buffer, num);
bw_pos += num;
return(0);
}
/* buffering_close() - writes out remaining buffered data before closing
* file.
*
*/
int buffering_close(int fd)
{
if (fd == bw_fd && bw_pos > 0) {
/* write out remaining data and clean up */
if (blocking_write(fd, bw_outbuf, bw_pos)) {
perror("write (in buffering_close)");
}
bw_fd = -1;
bw_pos = 0;
}
return(close(fd));
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright: GNU Public License 2 applies
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
* (C) 1998 Monty <xiphmont@mit.edu>
*
*/
extern long blocking_write(int outf, char *buffer, long i_num);

View File

@@ -0,0 +1,352 @@
.TH CDPARANOIA 1 "02 Mar 2001"
.SH NAME
cdparanoia 9.8 (Paranoia release III) \- an audio CD reading utility which includes extra data verification features
.SH SYNOPSIS
.B cdparanoia
.RB [ options ]
.B span
.RB [ outfile ]
.SH DESCRIPTION
.B cdparanoia
retrieves audio tracks from CDDA capable CDROM drives. The data can
be saved to a file or directed to standard output in WAV, AIFF, AIFF-C
or raw format. Most ATAPI, SCSI and several proprietary CDROM drive
makes are supported;
.B cdparanoia
can determine if the target drive is CDDA capable.
.P
In addition to simple reading,
.B cdparanoia
adds extra-robust data verification, synchronization, error handling
and scratch reconstruction capability.
.SH OPTIONS
.TP
.B \-v --verbose
Be absurdly verbose about the autosensing and reading process. Good
for setup and debugging.
.TP
.B \-q --quiet
Do not print any progress or error information during the reading process.
.TP
.B \-e --stderr-progress
Force output of progress information to stderr (for wrapper scripts).
.TP
.B \-V --version
Print the program version and quit.
.TP
.B \-Q --query
Perform CDROM drive autosense, query and print the CDROM table of
contents, then quit.
.TP
.B \-s --search-for-drive
Forces a complete search for a cdrom drive, even if the /dev/cdrom link exists.
.TP
.B \-h --help
Print a brief synopsis of
.B cdparanoia
usage and options.
.TP
.B \-p --output-raw
Output headerless data as raw 16 bit PCM data with interleaved samples in host byte order. To force little or big endian byte order, use
.B \-r
or
.B \-R
as described below.
.TP
.B \-r --output-raw-little-endian
Output headerless data as raw 16 bit PCM data with interleaved samples in LSB first byte order.
.TP
.B \-R --output-raw-big-endian
Output headerless data as raw 16 bit PCM data with interleaved samples in MSB first byte order.
.TP
.B \-w --output-wav
Output data in Micro$oft RIFF WAV format (note that WAV data is always
LSB first byte order).
.TP
.B \-f --output-aiff
Output data in Apple AIFF format (note that AIFC data is
always in MSB first byte order).
.TP
.B \-a --output-aifc
Output data in uncompressed Apple AIFF-C format (note that AIFF-C data is
always in MSB first byte order).
.TP
.BI "\-B --batch "
Cdda2wav-style batch output flag; cdparanoia will split the output
into multiple files at track boundaries. Output file names are
prepended with 'track#.'
.TP
.B \-c --force-cdrom-little-endian
Some CDROM drives misreport their endianness (or do not report it at
all); it's possible that cdparanoia will guess wrong. Use
.B \-c
to force cdparanoia to treat the drive as a little endian device.
.TP
.B \-C --force-cdrom-big-endian
As above but force cdparanoia to treat the drive as a big endian device.
.TP
.BI "\-n --force-default-sectors " n
Force the interface backend to do atomic reads of
.B n
sectors per read. This number can be misleading; the kernel will often
split read requests into multiple atomic reads (the automated Paranoia
code is aware of this) or allow reads only wihin a restricted size
range.
.B This option should generally not be used.
.TP
.BI "\-d --force-cdrom-device " device
Force the interface backend to read from
.B device
rather than the first readable CDROM drive it finds. This can be used
to specify devices of any valid interface type (ATAPI, SCSI or
proprietary).
.TP
.BI "\-g --force-generic-device " device
This option is used along with
.B \-d
when one wants explicit control in setting both the SCSI cdrom and
generic devices seperately. This option is only useful on
non-standard SCSI setups.
.TP
.BI "\-S --force-read-speed " number
Use this option explicitly to set the read rate of the CD drive (where
supported). This can reduce underruns on machines with slow disks, or
which are low on memory.
.TP
.BI "\-t --toc-offset " number
Use this option to force the entire disc LBA addressing to shift by
the given amount; the value is added to the beginning offsets in the
TOC. This can be used to shift track boundaries for the whole disc
manually on sector granularity. The next option does something
similar...
.TP
.BI "\-T --toc-bias "
Some drives (usually random Toshibas) report the actual track
beginning offset values in the TOC, but then treat the beginning of
track 1 index 1 as sector 0 for all read operations. This results in
every track seeming to start too late (losing a bit of the beginning
and catching a bit of the next track).
.B \-T
accounts for this behavior. Note that this option will cause
cdparanoia to attempt to read sectors before or past the known user
data area of the disc, resulting in read errors at disc edges on most
drives and possibly even hard lockups on some buggy hardware.
.TP
.BI "\-O --sample-offset " number
Use this option to force the entire disc to shift sample position
output by the given amount; This can be used to shift track boundaries
for the whole disc manually on sample granularity. Note that this will
cause cdparanoia to attempt to read partial sectors before or past the
known user data area of the disc, probably causing read errors on most
drives and possibly even hard lockups on some buggy hardware.
.TP
.B \-Z --disable-paranoia
Disable
.B all
data verification and correction features. When using -Z, cdparanoia
reads data exactly as would cdda2wav with an overlap setting of zero.
This option implies that
.B \-Y
is active.
.TP
.B \-z --never-skip[=max_retries]
Do not accept any skips; retry forever if needed. An optional maximum
number of retries can be specified; for comparison, default without -z is
currently 20.
.TP
.B \-Y --disable-extra-paranoia
Disables intra-read data verification; only overlap checking at read
boundaries is performed. It can wedge if errors occur in the attempted overlap area. Not recommended.
.TP
.B \-X --abort-on-skip
If the read skips due to imperfect data, a scratch, whatever, abort reading this track. If output is to a file, delete the partially completed file.
.SH OUTPUT SMILIES
.TP
.B
:-)
Normal operation, low/no jitter
.TP
.B
:-|
Normal operation, considerable jitter
.TP
.B
:-/
Read drift
.TP
.B
:-P
Unreported loss of streaming in atomic read operation
.TP
.B
8-|
Finding read problems at same point during reread; hard to correct
.TP
.B
:-0
SCSI/ATAPI transport error
.TP
.B
:-(
Scratch detected
.TP
.B
;-(
Gave up trying to perform a correction
.TP
.B
8-X
Aborted read due to known, uncorrectable error
.TP
.B
:^D
Finished extracting
.SH PROGRESS BAR SYMBOLS
.TP
.B
<space>
No corrections needed
.TP
.B
-
Jitter correction required
.TP
.B
+
Unreported loss of streaming/other error in read
.TP
.B
!
Errors found after stage 1 correction; the drive is making the
same error through multiple re-reads, and cdparanoia is having trouble
detecting them.
.TP
.B
e
SCSI/ATAPI transport error (corrected)
.TP
.B
V
Uncorrected error/skip
.SH SPAN ARGUMENT
The span argument specifies which track, tracks or subsections of
tracks to read. This argument is required.
.B NOTE:
Unless the span is a simple number, it's generally a good idea to
quote the span argument to protect it from the shell.
.P
The span argument may be a simple track number or an offset/span
specification. The syntax of an offset/span takes the rough form:
.P
1[ww:xx:yy.zz]-2[aa:bb:cc.dd]
.P
Here, 1 and 2 are track numbers; the numbers in brackets provide a
finer grained offset within a particular track. [aa:bb:cc.dd] is in
hours/minutes/seconds/sectors format. Zero fields need not be
specified: [::20], [:20], [20], [20.], etc, would be interpreted as
twenty seconds, [10:] would be ten minutes, [.30] would be thirty
sectors (75 sectors per second).
.P
When only a single offset is supplied, it is interpreted as a starting
offset and ripping will continue to the end of the track. If a single
offset is preceeded or followed by a hyphen, the implicit missing
offset is taken to be the start or end of the disc, respectively. Thus:
.TP
.B 1:[20.35]
Specifies ripping from track 1, second 20, sector 35 to the end of
track 1.
.TP
.B 1:[20.35]-
Specifies ripping from 1[20.35] to the end of the disc
.TP
.B \-2
Specifies ripping from the beginning of the disc up to (and including) track 2
.TP
.B \-2:[30.35]
Specifies ripping from the beginning of the disc up to 2:[30.35]
.TP
.B 2-4
Specifies ripping from the beginning of track 2 to the end of track 4.
.P
Again, don't forget to protect square brackets and preceeding hyphens from
the shell.
.SH EXAMPLES
A few examples, protected from the shell:
.TP
Query only with exhaustive search for a drive and full reporting of autosense:
.P
cdparanoia -vsQ
.TP
Extract an entire disc, putting each track in a seperate file:
.P
cdparanoia -B
.TP
Extract from track 1, time 0:30.12 to 1:10.00:
.P
cdparanoia "1[:30.12]-1[1:10]"
.TP
Extract from the beginning of the disc up to track 3:
.P
cdparanoia -- "-3"
.TP
The "--" above is to distinguish "-3" from an option flag.
.SH OUTPUT
The output file argument is optional; if it is not specified,
cdparanoia will output samples to one of
.BR cdda.wav ", " cdda.aifc ", or " cdda.raw
depending on whether
.BR \-w ", " \-a ", " \-r " or " \-R " is used (" \-w
is the implicit default). The output file argument of
.B \-
specifies standard output; all data formats may be piped.
.SH ACKNOWLEDGEMENTS
Cdparanoia sprang from and once drew heavily from the interface of
Heiko Eissfeldt's (heiko@colossus.escape.de) 'cdda2wav'
package. Cdparanoia would not have happened without it.
.P
Joerg Schilling has also contributed SCSI expertise through his
generic SCSI transport library.
.P
.SH AUTHOR
Monty <monty@xiph.org>
.P
Cdparanoia's homepage may be found at:
http://www.xiph.org/paranoia/

View File

@@ -0,0 +1,354 @@
.TH CDPARANOIA 1
.\" Translated Sun Aug 22 18:02:41 JST 1999
.\" by FUJIWARA Teruyoshi <fujiwara@linux.or.jp>
.SH ̾<><CCBE>
cdparanoia (Paranoia release III) \- <20><><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD> CD <20>ɤ߼<C9A4><DFBC><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̤ʥǡ<CAA5><C7A1><EFBFBD><EFBFBD>ȹ絡ǽ<E7B5A1><C7BD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD>
.SH <20><><EFBFBD><EFBFBD>
<EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>III <20><><EFBFBD><EFBFBD><EAA1BC><EFBFBD><EFBFBD>9.6 (17 Aug 1999)
.SH <20><><EFBFBD><EFBFBD>
.B cdparanoia
.RB [ options ]
.B span
.RB [ outfile ]
.SH <20><><EFBFBD><EFBFBD>
.B cdparanoia
<EFBFBD><EFBFBD> CD-DA <20><>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CD-ROM <20>ɥ饤<C9A5>֤<EFBFBD><D6A4><EFBFBD><E9A5AA><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>å<EFBFBD><C3A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><D0A4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WAV, AIFF, AIFF-C, raw <20><><EFBFBD><EFBFBD><EFBFBD>ǥե<C7A5><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥<EFBFBD><CBA5><EFBFBD><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EBA4B3>
<EFBFBD>䡢ɸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۤȤ<EFBFBD><EFBFBD>ɤ<EFBFBD> ATAPI, SCSI, <20><EFBFBD><E1A1BC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
<EFBFBD><EFBFBD> CD-ROM <20>ɥ饤<C9A5>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>ݡ<EFBFBD><DDA1>Ȥ<EFBFBD><C8A4><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4>ޤ<EFBFBD><DEA4><EFBFBD>
.B cdparanoia
<EFBFBD><EFBFBD><EFBFBD>оݤΥɥ饤<EFBFBD>֤<EFBFBD> CD-DA <20><>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD><EFBFBD>äƤ<C3A4><C6A4><EFBFBD>ɤ<EFBFBD><C9A4><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD>̤Ǥ<CCA4><C7A4>ޤ<EFBFBD><DEA4><EFBFBD>
.P
ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥʤ<EFBFBD><EFBFBD><EFBFBD>
.B cdparanoia
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̤˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʥǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ絡ǽ<EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>äƤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.SH <20><><EFBFBD>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-v --verbose
<EFBFBD><EFBFBD>ư<EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ν<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤĤ<EFBFBD><EFBFBD>ơ<EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۤɾ<EFBFBD>Ĺ<EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥХå<EFBFBD><EFBFBD>κݤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-q --quiet
<EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD><EFBFBD>ʹԾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-e --stderr-progress
<EFBFBD>ʹԾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>åѥ<C3A5><D1A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץȤΤ<C8A4><CEA4><EFBFBD><EFBFBD><EFBFBD><><EFBFBD><EFBFBD><E9A1BC><EFBFBD>Ϥ˽<CFA4><CBBD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B \-V --version
<EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΥС<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-Q --query
CD-ROM <20>ɥ饤<C9A5>֤μ<D6A4>ư<EFBFBD><C6B0><EFBFBD>Ф<EFBFBD><D0A4>Ԥ<EFBFBD><D4A4><EFBFBD>CD-ROM <20><> TOC <20><><EFBFBD><EFBFBD><E4A4A4><EFBFBD><EFBFBD><EFA4BB>ɽ<EFBFBD><C9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-s --search-for-drive
<EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD> /dev/cdrom <20>Υ<EFBFBD><CEA5>󥯤<EFBFBD>¸<EFBFBD>ߤ<EFBFBD><DFA4>Ƥ<EFBFBD><C6A4>Ƥ⡢CD-ROM <20>ɥ饤<C9A5>֤δ<D6A4><CEB4><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-h --help
.B cdparanoia
<EFBFBD>λȤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-p --output-raw
<EFBFBD>إå<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>Υǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۥ<EFBFBD><EFBFBD>ȤΥХ<EFBFBD><EFBFBD>Ƚ<EFBFBD><EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>󥿥꡼<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܤ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץ벻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD> raw <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20>ӥå<D3A5> PCM <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4>ƽ<EFBFBD><C6BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD><DEA4><EFBFBD>
<EFBFBD>Х<EFBFBD><EFBFBD>Ƚ<EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>ƥ<EFBFBD><EFBFBD>ȥ륨<EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>󤢤뤤<EFBFBD>ϥӥå<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ϡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҥ<EFBFBD>
.B \-r
<EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.B \-R
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȤäƤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-r --output-raw-little-endian
<EFBFBD>إå<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>Υǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LSB first <20>ΥХ<CEA5><D0A5>Ƚ<EFBFBD><C8BD>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>󥿥꡼<F3A5BFA5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܤ<EFBFBD><DCA4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץ벻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD> raw <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20>ӥå<D3A5> PCM <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4>ƽ<EFBFBD><C6BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B \-R --output-raw-big-endian
<EFBFBD>إå<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>Υǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MSB first <20>ΥХ<CEA5><D0A5>Ƚ<EFBFBD><C8BD>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>󥿥꡼<F3A5BFA5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܤ<EFBFBD><DCA4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץ벻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD> raw <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 16 <20>ӥå<D3A5> PCM <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4>ƽ<EFBFBD><C6BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B \-w --output-wav
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Micro$oft <20><> RIFF WAV <20><><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD>(WAV <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>ΥХ<CEA5><D0A5>Ƚ<EFBFBD><C8BD><EFBFBD>
ɬ<EFBFBD><EFBFBD> LSB first <20>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><>
.TP
.B \-f --output-aiff
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Apple <20><> AIFF <20><><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD>(AIFC <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>ΥХ<CEA5><D0A5>Ƚ<EFBFBD><C8BD><EFBFBD>ɬ<EFBFBD><C9AC>
MSB first <20>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><>
.TP
.B \-a --output-aifc
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Apple AIFF-C <20><><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD>(AIFF-C <20>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>ΥХ<CEA5><D0A5><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɬ<EFBFBD><EFBFBD> MSB first <20>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><>
.TP
.BI "\-B --batch "
cdda2wav <20><><EFBFBD><EFBFBD><EFBFBD>ΥХå<D0A5><C3A5><EFBFBD><EFBFBD>Ϥ<EFBFBD><CFA4>Ԥ<EFBFBD><D4A4>ޤ<EFBFBD><DEA4><EFBFBD>cdparanoia <20>Ͻ<EFBFBD><CFBD>Ϥ<EFBFBD><CFA4>ȥ<EFBFBD><C8A5>å<EFBFBD><C3A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ʣ<EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʬ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD>ʬ<EFBFBD>ϡ<EFBFBD>'track(<28>ֹ<EFBFBD>)'
<EFBFBD>Ȥʤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-c --force-cdrom-little-endian
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CD-ROM <20>ϴְ<CFB4><D6B0>ä<EFBFBD><C3A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤷤ޤ<F0A4B7A4>(<28><><EFBFBD><EFBFBD>ϥ<EFBFBD><CFA5><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>˴ؤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤷤ޤ<EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><CEA4>ᡢcdparanoia <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ְ㤨<EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɥ饤<EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ륨<EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΥǥХ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD>
cdparanoia <20>˰<EFBFBD><CBB0><EFBFBD><EFA4BB><EFBFBD>ˤϡ<CBA4>
.B \-c
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-C --force-cdrom-big-endian
<EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εդǡ<EFBFBD><EFBFBD>ǥХ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӥå<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΥǥХ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD>
cdparanoia <20>˰<EFBFBD><CBB0><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.BI "\-n --force-default-sectors " n
<EFBFBD><EFBFBD><EFBFBD>󥿥ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΥХå<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ<EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>Ǿ<EFBFBD>ñ<EFBFBD>̤<EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1 <20><><EFBFBD><EFBFBD><EFBFBD>ɤ߼<C9A4><DFBC><EFBFBD>Ȥ<EFBFBD>
.B n
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򵯤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͥ<EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD>ñ<EFBFBD>̤<EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD>(cdparanoia <20>ˤ<EFBFBD><CBA4>뼫ư<EBBCAB><C6B0><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD><CFA4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>ޤ<EFBFBD><><CAA3><EFBFBD>Ĥ<EFBFBD>ʬ<EFBFBD><EFBFBD><EFBFBD><EBA4AB><EFBFBD><EFBFBD><EFBFBD>¤<EFBFBD><C2A4>줿<EFBFBD><EFBFBD><E7A4AD><EFBFBD><EFBFBD><EFBFBD>ϰϤǤ<CFA4><C7A4><EFBFBD>
<EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B <20><><EFBFBD>̤Ϥ<CCA4><CFA4>Υ<EFBFBD><CEA5>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4>٤<EFBFBD><D9A4>ǤϤ<C7A4><CFA4><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD><EFBFBD><EFBFBD>
.TP
.BI "\-d --force-cdrom-device " device
<EFBFBD><EFBFBD><EFBFBD>󥿥ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΥХå<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>򡢺ǽ<EFBFBD><EFBFBD>˸<EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ǽ<EFBFBD><EFBFBD> CD-ROM <20>ɥ饤<C9A5>֤ǤϤʤ<CFA4><CAA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EAA4B7>
.B device
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥϡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD>ǽ<EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD>դ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>󥿥ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(ATAPI, SCSI, <20><EFBFBD><E1A1BC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>ĥǥХ<C7A5><D0A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA4B3>
<EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.BI "\-g --force-generic-device " device
<EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϡ<EFBFBD>SCSI CD-ROM <20><><EFBFBD><EFBFBD><EFBFBD>ѥǥХ<C7A5><D0A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ū<EFBFBD><C5AA><EFBFBD>̡<EFBFBD><CCA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-d
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ߹<EFBFBD><EFBFBD><EFBFBD>ƻȤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ω<EFBFBD>ĤΤϡ<EFBFBD>SCSI <20><>
<EFBFBD><EFBFBD><EFBFBD>꤬ɸ<EFBFBD><EFBFBD><EFBFBD>Ȱۤʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>
.TP
.BI "\-S --force-read-speed " number
CD <20>ɥ饤<C9A5>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߹<C9A4><DFB9><EFBFBD>®<EFBFBD>٤<EFBFBD><D9A4><EFBFBD><EFBFBD><EFBFBD><EAA4B9><EFBFBD>ˤϡ<CBA4><CFA1><EFBFBD><EFBFBD>Υ<EFBFBD><CEA5>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ū<EFBFBD><C5AA>
<EFBFBD>ȤäƤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ɥ饤<C9A5>֤<EFBFBD><D6A4>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><CEA5>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѥ<EFBFBD><D1A4><EFBFBD><EFBFBD>ȡ<EFBFBD>
<EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>٤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򸺤餹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-Z --disable-paranoia
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD>
.b <20><><EFBFBD><EFBFBD>
̵<EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>-Z <20><><EFBFBD>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѥ<EFBFBD><D1A4><EFBFBD><EFBFBD>ȡ<EFBFBD>cdparanoia <20><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>åפ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>꤬ 0 <20>Ǥ<EFBFBD><C7A4><EFBFBD> cdda2wav <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>˥ǡ<CBA5><C7A1><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-W ,
.B \-X ,
.B \-Y
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͭ<EFBFBD><EFBFBD><EFBFBD>ˤʤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-Z \-W \-X \-Y
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD>
.B <20><><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ʤ<EFBFBD><EFBFBD>ʤ顢
.B \-W
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-Z
<EFBFBD>ޤǤΥ<EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ<EFBFBD><EFBFBD>Υ<EFBFBD><EFBFBD>٥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ū<EFBFBD><EFBFBD><EFBFBD>Ѥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ºݤ<EFBFBD>ͭ<EFBFBD><EFBFBD>
<EFBFBD>ˤʤ<EFBFBD><EFBFBD>ΤϺǸ<EFBFBD><EFBFBD>˻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-Y --disable-extra-paranoia
<EFBFBD>ɤ߼<EFBFBD><EFBFBD>ä<EFBFBD><EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD>󡣤Ĥޤꡢ
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD>ʬ<EFBFBD>Υ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-X --disable-scratch-detection
<EFBFBD>ȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǤϽ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ鷺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>ƴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-X
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD><EFBFBD> CD <20><>Ϳ<EFBFBD><CDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cdparanoia <20><><EFBFBD>ɤ߼<C9A4><DFBC><EFBFBD>
<EFBFBD>μ<EFBFBD><EFBFBD>Ԥ򵯤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B \-W --disable-scratch-repair
<EFBFBD><EFBFBD><EFBFBD>򸡽Ф<EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݤĽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>줿<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ν<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϹԤ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>󡣥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ν<EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD>(
.RB \-i
<EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>Ƥν<C6A4><CEBD>Υե졼<D5A5><ECA1BC><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><CBBD>Ϥ<EFBFBD><CFA4><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
.SH <20><><EFBFBD>Ϥ<EFBFBD><CFA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʸ<EFBFBD><CAB8>
.TP
.B
:-)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD><EFBFBD><EFBFBD><EFBFBD>å<EFBFBD><EFBFBD>Ͼ<EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD>
.TP
.B
:-|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD><EFBFBD><EFBFBD><EFBFBD>å<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>
.TP
.B
:-/
<EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥɥ<EFBFBD><EFBFBD>եȤ<EFBFBD>ȯ<EFBFBD><EFBFBD>
.TP
.B
:-P
<EFBFBD>Ǿ<EFBFBD>ñ<EFBFBD>̤<EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤵤<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>ʤ<EFBFBD>»<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ꡼<EFBFBD>ߥ󥰤ˤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B
8-|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥä<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B
:-0
SCSI/ATAPI <20>Υǡ<CEA5><C7A1><EFBFBD>ž<EFBFBD><C5BE><EFBFBD><EFBFBD><EFBFBD>
.TP
.B
:-(
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>줿
.TP
.B
;-(
<EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򤢤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>᤿
.TP
.B
:^D
<EFBFBD>ɤ߼<EFBFBD><EFBFBD>꽪λ
.SH <20>ʹ<EFBFBD>ɽ<EFBFBD><C9BD><EFBFBD>ΰ<EFBFBD>̣
.TP
.B
<<3C><><EFBFBD>ڡ<EFBFBD><DAA1><EFBFBD>>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.TP
.B
-
<EFBFBD><EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɬ<EFBFBD><EFBFBD>
.TP
.B
+
<EFBFBD><EFBFBD><EFBFBD>𤵤<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>ʤ<EFBFBD>»<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ꡼<EFBFBD>ߥ󥰤ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̤Υ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤ߼<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.TP
.B
!
<EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD>θ<EFBFBD><CEB8>˥<EFBFBD><CBA5><EFBFBD><E9A1BC><EFBFBD><EFBFBD><EFBFBD>Ĥ<EFBFBD><C4A4>ä<EFBFBD><C3A4><EFBFBD><EFBFBD>ɤ߼<C9A4><DFBC><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>󷫤<EFBFBD><F3B7ABA4>֤<EFBFBD><D6A4>Ƥ<EFBFBD>
Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cdparanoia <20>Ϥ<EFBFBD><CFA4>Υ<EFBFBD><CEA5><EFBFBD>򤦤ޤ<F2A4A6A4><DEA4><EFBFBD><EFBFBD>ФǤ<D0A4><C7A4>ʤ<EFBFBD><CAA4><EFBFBD>
.TP
.B
e
SCSI/ATAPI <20>Υǡ<CEA5><C7A1><EFBFBD>ž<EFBFBD><C5BE><EFBFBD><EFBFBD><EFBFBD>顼(<28><><EFBFBD><EFBFBD><EFBFBD>Ѥ<EFBFBD>)
.TP
.B
V
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>顼/<2F>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>Υ<EFBFBD><CEA5><EFBFBD><EFBFBD>å<EFBFBD>
.SH <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 'span'
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> span <20>ϡ<EFBFBD><CFA1>ɤ߼<C9A4><DFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4>ȥ<EFBFBD><C8A5>å<EFBFBD><C3A5>ޤ<EFBFBD><DEA4>ϥȥ<CFA5><C8A5>å<EFBFBD><C3A5>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɬ<EFBFBD><EFBFBD>ɬ<EFBFBD>פǤ<EFBFBD><EFBFBD><EFBFBD>
.B <20><><EFBFBD><EFBFBD>:
span <20><>ñ<EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥʤ<C7A4><CAA4><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> span <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4>ޤ<EFBFBD><DEA4>ʤ<EFBFBD>
<EFBFBD><EFBFBD>˥<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̤Ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.P
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> span <20>ϡ<EFBFBD>ñ<EFBFBD>ʤ<EFBFBD><CAA4>ȥ<EFBFBD><C8A5>å<EFBFBD><C3A5>ֹ椫<D6B9><E6A4AB><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><D5A5>åȤȥ<C8A4><C8A5>ѥ<EFBFBD><D1A5><EFBFBD><EFBFBD>ȹ礻<C8B9>λ<EFBFBD><CEBB><EFBFBD>
<EFBFBD>Ȥʤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD>åȤȥ<EFBFBD><EFBFBD>ѥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȹ礻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD>ϡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ˤʤ<EFBFBD><EFBFBD>ޤ<EFBFBD>:
.P
1[ww:xx:yy.zz]-2[aa:bb:cc.dd]
.P
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20><> 2 <20>ϥȥ<CFA5><C8A5>å<EFBFBD><C3A5>ֹ<EFBFBD><D6B9>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD>ѳ<EFBFBD><D1B3>̤<EFBFBD><CCA4><EFBFBD><EFBFBD>ο<EFBFBD><CEBF>ͤϡ<CDA4><CFA1><EFBFBD><EFBFBD><EFBFBD>줿<EFBFBD>ȥ<EFBFBD><C8A5>å<EFBFBD>
<EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>٤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD>åȻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD>[aa:bb:cc.dd] <20><>
<EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD>/ʬ/<2F><>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>פη<D7A4><CEB7><EFBFBD><EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD>ͤ<EFBFBD> 0 <20>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤϻ<C9A4><CFBB><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD>󡣤Ĥޤ<EFBFBD> [::20], [:20], [20], [20.] <20><><EFBFBD><EFBFBD> 20 <20>äȲ<C3A4><C8B2><EFBFBD>
[10:] <20><> 10 <20>äȲ<C3A4><C8B2><EFBFBD>졢[.30] <20><> 30 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD><E1A4B5><EFBFBD>ޤ<EFBFBD>(75 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1 <20>äǤ<C3A4>)<29><>
.P
<EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD>åȤ<EFBFBD> 1 <20>Ĥ<EFBFBD><C4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϳ<EFBFBD><CFB3>ϰ<EFBFBD><CFB0>֤Υ<D6A4><CEA5>ե<EFBFBD><D5A5>åȤ<C3A5>ɽ<EFBFBD><C9BD><EFBFBD><EFBFBD>
<EFBFBD>ۤ<EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD>Υȥ<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD>ν<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǹԤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD>åȤ<EFBFBD> 1 <20>Ĥ<EFBFBD><C4A4><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˥ϥ<EFBFBD><EFBFBD>ե<EFBFBD>(-)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤϡ<CBA4><CFA1><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><C6A4><EFBFBD>ե<EFBFBD><D5A5>åȤ<C3A5>
<EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>Ʋ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD><EFBFBD>˼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD>:
.TP
.B 1:[20.35]
<EFBFBD>ȥ<EFBFBD><EFBFBD>å<EFBFBD> 1 <20><> 20 <20>á<EFBFBD>35 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0>֤<EFBFBD><D6A4><EFBFBD>ȥ<EFBFBD><C8A5>å<EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǤ<DEA4><C7A4>ۤ<EFBFBD>
<EFBFBD>Ф<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.TP
.B 1:[20.35]-
1[20.35] <20>ΰ<EFBFBD><CEB0>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǤ<DEA4><C7A4>ۤ<EFBFBD><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B \-2
<EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD>å<EFBFBD> 2 <20>ޤ<EFBFBD>(<28>ȥ<EFBFBD><C8A5>å<EFBFBD> 2 <20><><EFBFBD>ޤߤޤ<DFA4>)<29><><EFBFBD>ۤ<EFBFBD><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B \-2:[30.35]
<EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2:[30.35] <20>ΰ<EFBFBD><CEB0>֤ޤǵۤ<C7B5><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD><DEA4><EFBFBD>
.TP
.B 2-4
<EFBFBD>ȥ<EFBFBD><EFBFBD>å<EFBFBD> 2 <20><><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>å<EFBFBD> 4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤǤ<DEA4><C7A4>ۤ<EFBFBD><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD><DEA4><EFBFBD>
.P
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ˤʤ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѳ<EFBFBD><EFBFBD>̤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD>ˤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><EFBFBD>ե<EFBFBD><EFBFBD><EFBFBD>ɬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.SH <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>ޤ᤿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򤤤<EFBFBD><EFBFBD>Ĥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD>:
.TP
<EFBFBD>ɥ饤<EFBFBD>֤<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD><EFBFBD>Ū<EFBFBD>˹Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD><EFBFBD><EFBFBD>Фη<EFBFBD><EFBFBD>̤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤷤ޤ<EFBFBD>:
.P
cdparanoia -vsQ
.TP
<EFBFBD>ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><EFBFBD>ۤ<EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Υȥ<EFBFBD><EFBFBD>å<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̡<EFBFBD><EFBFBD>Υե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>ޤ<EFBFBD>:
.P
cdparanoia -B "1-"
.TP
<EFBFBD>ȥ<EFBFBD><EFBFBD>å<EFBFBD> 1 <20>λ<EFBFBD><CEBB><EFBFBD> 0:30.12 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1:10.00 <20>ޤǤ<DEA4><C7A4>ۤ<EFBFBD><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD>:
.P
cdparanoia "1[:30.12]-1[1:10]"
.TP
<EFBFBD>ȥ<EFBFBD><EFBFBD>å<EFBFBD> 1 <20>λ<EFBFBD><CEBB><EFBFBD> 0:30.12 <20><><EFBFBD><EFBFBD> 1 ʬ<>֤Υǡ<CEA5><C7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۤ<EFBFBD><DBA4>Ф<EFBFBD><D0A4>ޤ<EFBFBD>:
.P
cdparanoia "1[:30.12]-[1:00]"
.SH <20><><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ϥե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͼ<EFBFBD>ά<EFBFBD><EFBFBD>ǽ<EFBFBD>Ǥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD>ʤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
cdparanoia <20>ϥ<EFBFBD><CFA5><EFBFBD><EFBFBD>ץ벻<D7A5><EBB2BB><EFBFBD><EFBFBD>
.BR cdda.wav ", " cdda.aifc ", " cdda.raw
<EFBFBD>Τ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤΥե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><EFBFBD>ϡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ץ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.BR \-w ", " \-a ", " \-r "," \-R
<EFBFBD>Τ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˤ<EFBFBD><EFBFBD>äƷ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD>ޤ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD><EFBFBD>
.BR \-w
<EFBFBD><EFBFBD><EFBFBD>ǥե<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͤǤ<EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>ϥե<CFA5><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EAA4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.B \-
<EFBFBD>ʤ<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD>ɸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϥ<EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>ƹԤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɤΥǡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ѥ<EFBFBD><EFBFBD>פ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>Ȥ<EFBFBD><EFBFBD>Ǥ<EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD>
.SH <20>ռ<EFBFBD>
cdparanoia <20>δ<EFBFBD><CEB4>Ȥʤä<CAA4><C3A4>Τ<EFBFBD> Heiko Eissfeldt <20><><EFBFBD><EFBFBD>
(heiko@colossus.escape.de)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 'cdda2wav' <20>ѥå<D1A5><C3A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><C7A4>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cdparanoia <20>Υ<EFBFBD><CEA5>󥿥ե<F3A5BFA5><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʬ<EFBFBD><CAAC> cdda2wav <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>äƤ<C3A4><C6A4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ΤǤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cdda2wav <20><><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>С<EFBFBD>cdparanoia <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȤϤʤ<CFA4><CAA4>ä<EFBFBD><C3A4><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.P
Joerg Schilling <20><><EFBFBD>󤬺<EFBFBD><F3A4ACBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SCSI <20>ǡ<EFBFBD><C7A1><EFBFBD>ž<EFBFBD><C5BE><EFBFBD><EFBFBD>֥<EFBFBD><D6A5><EFBFBD>顢SCSI
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>μ<EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD><EFBFBD><EFBFBD>ؤФ<EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.P
.SH <20><><EFBFBD><EFBFBD>
Monty <monty@xiph.org>
.P
cdparanoia <20>Υۡ<CEA5><DBA1><EFBFBD><EFBFBD>ڡ<EFBFBD><DAA1><EFBFBD><EFBFBD>ϰʲ<CFB0><CAB2>ξ<EFBFBD><CEBE><EFBFBD><EFBFBD>ˤ<EFBFBD><CBA4><EFBFBD><EFBFBD>ޤ<EFBFBD>:
.P
.ce
http://www.xiph.org/paranoia/

Some files were not shown because too many files have changed in this diff Show More