|
Packit |
cb6d3d |
/*
|
|
Packit |
cb6d3d |
Copyright (C) 2005-2006, 2008, 2011, 2014 Rocky Bernstein <rocky@gnu.org>
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
cb6d3d |
it under the terms of the GNU General Public License as published by
|
|
Packit |
cb6d3d |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
cb6d3d |
(at your option) any later version.
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
This program is distributed in the hope that it will be useful,
|
|
Packit |
cb6d3d |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
cb6d3d |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
cb6d3d |
GNU General Public License for more details.
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
You should have received a copy of the GNU General Public License
|
|
Packit |
cb6d3d |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
cb6d3d |
*/
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Simple program to show using libcdio's version of cdparanoia. */
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef HAVE_CONFIG_H
|
|
Packit |
cb6d3d |
# include "config.h"
|
|
Packit |
cb6d3d |
# define __CDIO_CONFIG_H__ 1
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#include <cdio/paranoia/cdda.h>
|
|
Packit |
cb6d3d |
#include <cdio/paranoia/paranoia.h>
|
|
Packit |
cb6d3d |
#include <cdio/cd_types.h>
|
|
Packit |
cb6d3d |
#include <stdio.h>
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef HAVE_STDLIB_H
|
|
Packit |
cb6d3d |
#include <stdlib.h>
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef HAVE_STRING_H
|
|
Packit |
cb6d3d |
#include <string.h>
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef WORDS_BIGENDIAN
|
|
Packit |
cb6d3d |
#define BIGENDIAN 1
|
|
Packit |
cb6d3d |
#else
|
|
Packit |
cb6d3d |
#define BIGENDIAN 0
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#define SKIP_TEST_RC 77
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#define MAX_SECTORS 50
|
|
Packit |
cb6d3d |
static uint8_t audio_buf[MAX_SECTORS][CDIO_CD_FRAMESIZE_RAW] = { {0}, };
|
|
Packit |
cb6d3d |
static paranoia_cb_mode_t audio_status[MAX_SECTORS];
|
|
Packit |
cb6d3d |
static unsigned int i = 0;
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
static void
|
|
Packit |
cb6d3d |
callback(long int inpos, paranoia_cb_mode_t function)
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
audio_status[i] = function;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
int
|
|
Packit |
cb6d3d |
main(int argc, const char *argv[])
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
cdrom_drive_t *d = NULL; /* Place to store handle given by cd-parapnioa. */
|
|
Packit |
cb6d3d |
driver_id_t driver_id;
|
|
Packit |
cb6d3d |
char **ppsz_cd_drives; /* List of all drives with a loaded CDDA in it. */
|
|
Packit |
cb6d3d |
int i_rc=0;
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* See if we can find a device with a loaded CD-DA in it. If successful
|
|
Packit |
cb6d3d |
drive_id will be set. */
|
|
Packit |
cb6d3d |
ppsz_cd_drives = cdio_get_devices_with_cap_ret(NULL, CDIO_FS_AUDIO, false,
|
|
Packit |
cb6d3d |
&driver_id);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if (ppsz_cd_drives && *ppsz_cd_drives) {
|
|
Packit |
cb6d3d |
/* Found such a CD-ROM with a CD-DA loaded. Use the first drive in
|
|
Packit |
cb6d3d |
the list. */
|
|
Packit |
cb6d3d |
d=cdda_identify(*ppsz_cd_drives, 1, NULL);
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
printf("-- Unable find or access a CD-ROM drive with an audio CD in it.\n");
|
|
Packit |
cb6d3d |
exit(SKIP_TEST_RC);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/** We had a bug in is_device when driver_id == DRIVER_UNKNOWN or
|
|
Packit |
cb6d3d |
DRIVER_DEVICE. Let's make sure we've fixed that problem. **/
|
|
Packit |
cb6d3d |
if (!cdio_is_device(*ppsz_cd_drives, DRIVER_UNKNOWN) ||
|
|
Packit |
cb6d3d |
!cdio_is_device(*ppsz_cd_drives, DRIVER_DEVICE))
|
|
Packit |
cb6d3d |
exit(99);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Don't need a list of CD's with CD-DA's any more. */
|
|
Packit |
cb6d3d |
cdio_free_device_list(ppsz_cd_drives);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* We'll set for verbose paranoia messages. */
|
|
Packit |
cb6d3d |
cdda_verbose_set(d, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if ( 0 != cdio_cddap_open(d) ) {
|
|
Packit |
cb6d3d |
printf("Unable to open disc.\n");
|
|
Packit |
cb6d3d |
exit(SKIP_TEST_RC);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Okay now set up to read up to the first 300 frames of the first
|
|
Packit |
cb6d3d |
audio track of the Audio CD. */
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
cdrom_paranoia_t *p = paranoia_init(d);
|
|
Packit |
cb6d3d |
lsn_t i_first_lsn = cdda_disc_firstsector(d);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if ( -1 == i_first_lsn ) {
|
|
Packit |
cb6d3d |
printf("Trouble getting starting LSN\n");
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
lsn_t i_lsn; /* Current LSN to read */
|
|
Packit |
cb6d3d |
lsn_t i_last_lsn = cdda_disc_lastsector(d);
|
|
Packit |
cb6d3d |
unsigned int i_sectors = i_last_lsn - i_first_lsn + 1;
|
|
Packit |
cb6d3d |
unsigned int j;
|
|
Packit |
cb6d3d |
unsigned int i_good = 0;
|
|
Packit |
cb6d3d |
unsigned int i_bad = 0;
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Set reading mode for full paranoia, but allow skipping sectors. */
|
|
Packit |
cb6d3d |
paranoia_modeset(p, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
for ( j=0; j<10; j++ ) {
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Pick a place to start reading. */
|
|
Packit |
cb6d3d |
i_lsn = i_first_lsn + (rand() % i_sectors);
|
|
Packit |
cb6d3d |
paranoia_seek(p, i_lsn, SEEK_SET);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
printf("-- Testing %d sectors starting at %ld\n",
|
|
Packit |
cb6d3d |
MAX_SECTORS, (long int) i_lsn);
|
|
Packit |
cb6d3d |
for ( i = 0;
|
|
Packit |
cb6d3d |
i < MAX_SECTORS && i_lsn <= i_last_lsn;
|
|
Packit |
cb6d3d |
i++, i_lsn++ ) {
|
|
Packit |
cb6d3d |
/* read a sector */
|
|
Packit |
cb6d3d |
int16_t *p_readbuf = paranoia_read(p, callback);
|
|
Packit |
cb6d3d |
char *psz_err=cdio_cddap_errors(d);
|
|
Packit |
cb6d3d |
char *psz_mes=cdio_cddap_messages(d);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
memcpy(audio_buf[i], p_readbuf, CDIO_CD_FRAMESIZE_RAW);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if (psz_mes || psz_err)
|
|
Packit |
cb6d3d |
printf("%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: "");
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
cdio_cddap_free_messages(psz_err);
|
|
Packit |
cb6d3d |
cdio_cddap_free_messages(psz_mes);
|
|
Packit |
cb6d3d |
if( !p_readbuf ) {
|
|
Packit |
cb6d3d |
printf("paranoia read error. Stopping.\n");
|
|
Packit |
cb6d3d |
goto out;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
/* Compare with the sectors from paranoia. */
|
|
Packit |
cb6d3d |
i_lsn -= MAX_SECTORS;
|
|
Packit |
cb6d3d |
for ( i = 0; i < MAX_SECTORS; i++, i_lsn++ ) {
|
|
Packit |
cb6d3d |
uint8_t readbuf[CDIO_CD_FRAMESIZE_RAW] = {0,};
|
|
Packit |
cb6d3d |
if ( PARANOIA_CB_READ == audio_status[i] ||
|
|
Packit |
cb6d3d |
PARANOIA_CB_VERIFY == audio_status[i] ) {
|
|
Packit |
cb6d3d |
/* We read the block via paranoia without an error. */
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if ( 0 == cdio_read_audio_sector(d->p_cdio, readbuf, i_lsn) ) {
|
|
Packit |
cb6d3d |
if ( BIGENDIAN != d->bigendianp ) {
|
|
Packit |
cb6d3d |
/* We will compare in the slow, pedantic way*/
|
|
Packit |
cb6d3d |
int j;
|
|
Packit |
cb6d3d |
for (j=0; j < CDIO_CD_FRAMESIZE_RAW ; j +=2) {
|
|
Packit |
cb6d3d |
if (audio_buf[i][j] != readbuf[j+1] &&
|
|
Packit |
cb6d3d |
audio_buf[i][j+1] != readbuf[j] ) {
|
|
Packit |
cb6d3d |
printf("LSN %ld doesn't match\n", (long int) i_lsn);
|
|
Packit |
cb6d3d |
i_bad++;
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
i_good++;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
if ( 0 != memcmp(audio_buf[i], readbuf,
|
|
Packit |
cb6d3d |
CDIO_CD_FRAMESIZE_RAW) ) {
|
|
Packit |
cb6d3d |
printf("LSN %ld doesn't match\n", (long int) i_lsn);
|
|
Packit |
cb6d3d |
i_bad++;
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
i_good++;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
printf("Skipping LSN %ld because of status: %s\n",
|
|
Packit |
cb6d3d |
(long int) i_lsn, paranoia_cb_mode2str[audio_status[i]]);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
printf("-- %u sectors compared okay %u sectors were different\n",
|
|
Packit |
cb6d3d |
i_good, i_bad);
|
|
Packit |
cb6d3d |
if (i_bad > i_good) i_rc = 1;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
out: paranoia_free(p);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
cdio_cddap_close(d);
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
exit(i_rc);
|
|
Packit |
cb6d3d |
}
|