Blame test/testparanoia.c

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
}