Add jitter simulation and jitter-correction testing.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: cdda.h,v 1.8 2005/01/22 03:43:03 rocky Exp $
|
||||
$Id: cdda.h,v 1.9 2005/01/22 18:11:32 rocky Exp $
|
||||
|
||||
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2001 Xiph.org
|
||||
@@ -111,26 +111,35 @@ struct cdrom_drive_s {
|
||||
|
||||
};
|
||||
|
||||
/**< under-run testing. The below bit is set for testing. */
|
||||
#define CDDA_TEST_UNDERRUN 16
|
||||
|
||||
#if TESTING_IS_FINISHED
|
||||
/** jitter testing. The first two bits are set to determine
|
||||
how much jitter to simulate.
|
||||
/**< jitter testing. The first two bits are set to determine
|
||||
the byte-distance we will jitter the data; 0 is no shifting.
|
||||
*/
|
||||
#define CDDA_TEST_JITTER_SMALL 1
|
||||
#define CDDA_TEST_JITTER_LARGE 2
|
||||
#define CDDA_TEST_JITTER_MASSIVE 3
|
||||
|
||||
/**< jitter testing. Set the below bit to always cause jittering on reads.
|
||||
The below bit only has any effect if the first two (above) bits are
|
||||
nonzero. If the above bits are set, but the below bit isn't we'll
|
||||
jitter 90% of the time.
|
||||
*/
|
||||
#define CDDA_TEST_ALWAYS_JITTER 4
|
||||
|
||||
/** fragment testing */
|
||||
#define CDDA_TEST_FRAG_SMALL (1<<2)
|
||||
#define CDDA_TEST_FRAG_LARGE (2<<2)
|
||||
#define CDDA_TEST_FRAG_MASSIVE (3<<2)
|
||||
#define CDDA_TEST_FRAG_SMALL (1<<3)
|
||||
#define CDDA_TEST_FRAG_LARGE (2<<3)
|
||||
#define CDDA_TEST_FRAG_MASSIVE (3<<3)
|
||||
|
||||
/**< under-run testing. The below bit is set for testing. */
|
||||
#define CDDA_TEST_UNDERRUN 64
|
||||
|
||||
#if TESTING_IS_FINISHED
|
||||
|
||||
/** scratch testing */
|
||||
#define CDDA_TEST_SCRATCH 32
|
||||
#undef CDDA_TEST_BOGUS_BYTES 64
|
||||
#undef CDDA_TEST_DROPDUPE_BYTES 128
|
||||
#define CDDA_TEST_SCRATCH 128
|
||||
#undef CDDA_TEST_BOGUS_BYTES 256
|
||||
#undef CDDA_TEST_DROPDUPE_BYTES 512
|
||||
#endif /* TESTING_IS_FINISHED */
|
||||
|
||||
/** autosense functions */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: cooked_interface.c,v 1.12 2005/01/18 00:57:20 rocky Exp $
|
||||
$Id: cooked_interface.c,v 1.13 2005/01/22 18:11:32 rocky Exp $
|
||||
|
||||
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
|
||||
Original interface.c Copyright (C) 1994-1997
|
||||
@@ -69,33 +69,24 @@ cooked_setspeed(cdrom_drive_t *d, int i_speed)
|
||||
return cdio_set_speed(d->p_cdio, i_speed);
|
||||
}
|
||||
|
||||
/* read 'SectorBurst' adjacent sectors of audio sectors
|
||||
* to Buffer '*p' beginning at sector 'lSector'
|
||||
/* read 'i_sector' adjacent audio sectors
|
||||
* into buffer '*p' beginning at sector 'begin'
|
||||
*/
|
||||
|
||||
static long int
|
||||
cooked_read (cdrom_drive_t *d, void *p, lsn_t begin, long sectors)
|
||||
read_blocks (cdrom_drive_t *d, void *p, lsn_t begin, long i_sectors)
|
||||
{
|
||||
int retry_count,err;
|
||||
int retry_count = 0;
|
||||
int err;
|
||||
char *buffer=(char *)p;
|
||||
|
||||
/* read d->nsectors at a time, max. */
|
||||
sectors=( sectors > d->nsectors && d->nsectors > 0 ? d->nsectors : sectors);
|
||||
|
||||
/* If we are testing under-run correction, we will deliberately set
|
||||
what we read a frame short. */
|
||||
if (d->i_test_flags & CDDA_TEST_UNDERRUN )
|
||||
sectors--;
|
||||
|
||||
retry_count=0;
|
||||
|
||||
do {
|
||||
err = cdio_read_audio_sectors( d->p_cdio, buffer, begin, sectors);
|
||||
err = cdio_read_audio_sectors( d->p_cdio, buffer, begin, i_sectors);
|
||||
|
||||
if ( 0 != err ) {
|
||||
if (!d->error_retry) return -7;
|
||||
|
||||
if (sectors==1) {
|
||||
if (i_sectors==1) {
|
||||
/* *Could* be I/O or media error. I think. If we're at
|
||||
30 retries, we better skip this unhappy little
|
||||
sector. */
|
||||
@@ -111,8 +102,8 @@ cooked_read (cdrom_drive_t *d, void *p, lsn_t begin, long sectors)
|
||||
}
|
||||
|
||||
if(retry_count>4)
|
||||
if(sectors>1)
|
||||
sectors=sectors*3/4;
|
||||
if(i_sectors>1)
|
||||
i_sectors=i_sectors*3/4;
|
||||
retry_count++;
|
||||
if (retry_count>MAX_RETRIES) {
|
||||
cderror(d,"007: Unknown, unrecoverable error reading data\n");
|
||||
@@ -122,7 +113,115 @@ cooked_read (cdrom_drive_t *d, void *p, lsn_t begin, long sectors)
|
||||
break;
|
||||
} while (err);
|
||||
|
||||
return(sectors);
|
||||
return(i_sectors);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
JITTER_NONE = 0,
|
||||
JITTER_SMALL= 1,
|
||||
JITTER_LARGE= 2,
|
||||
JITTER_MASSIVE=3
|
||||
} jitter_baddness_t;
|
||||
|
||||
/* read 'i_sector' adjacent audio sectors
|
||||
* into buffer '*p' beginning at sector 'begin'
|
||||
*/
|
||||
|
||||
static long int
|
||||
jitter_read (cdrom_drive_t *d, void *p, lsn_t begin, long i_sectors,
|
||||
jitter_baddness_t jitter_badness)
|
||||
{
|
||||
static int i_jitter=0;
|
||||
int jitter_flag;
|
||||
long i_sectors_orig = i_sectors;
|
||||
long i_jitter_offset = 0;
|
||||
|
||||
char *p_buf=malloc(CDIO_CD_FRAMESIZE_RAW*(i_sectors+1));
|
||||
|
||||
if (d->i_test_flags & CDDA_TEST_ALWAYS_JITTER)
|
||||
jitter_flag = 1;
|
||||
else
|
||||
jitter_flag = (drand48() > .9) ? 1 : 0;
|
||||
|
||||
if (jitter_flag) {
|
||||
int i_coeff = 0;
|
||||
int i_jitter_sectors = 0;
|
||||
switch(jitter_badness) {
|
||||
case JITTER_SMALL : i_coeff = 4; break;
|
||||
case JITTER_LARGE : i_coeff = 32; break;
|
||||
case JITTER_MASSIVE: i_coeff = 128; break;
|
||||
case JITTER_NONE :
|
||||
default : ;
|
||||
}
|
||||
i_jitter = i_coeff * (int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
|
||||
|
||||
/* We may need to add another sector to compensate for the bytes that
|
||||
will be dropped off when jittering, and the begin location may
|
||||
be a little different.
|
||||
*/
|
||||
i_jitter_sectors = i_jitter / CDIO_CD_FRAMESIZE_RAW;
|
||||
|
||||
if (i_jitter >= 0)
|
||||
i_jitter_offset = i_jitter % CDIO_CD_FRAMESIZE_RAW;
|
||||
else {
|
||||
i_jitter_offset = CDIO_CD_FRAMESIZE_RAW -
|
||||
(-i_jitter % CDIO_CD_FRAMESIZE_RAW);
|
||||
i_jitter_sectors--;
|
||||
}
|
||||
|
||||
|
||||
if (begin + i_jitter_sectors > 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "jittering by %d, offset %ld\n", i_jitter,
|
||||
i_jitter_offset);
|
||||
cdmessage(d,buffer);
|
||||
|
||||
begin += i_jitter_sectors;
|
||||
i_sectors ++;
|
||||
} else
|
||||
i_jitter_offset = 0;
|
||||
|
||||
}
|
||||
|
||||
i_sectors = read_blocks(d, p_buf, begin, i_sectors);
|
||||
|
||||
if (i_sectors < 0) return i_sectors;
|
||||
|
||||
if (i_sectors < i_sectors_orig)
|
||||
/* Had to reduce # of sectors due to read errors. So give full amount,
|
||||
with no jittering. */
|
||||
memcpy(p, p_buf, i_sectors*CDIO_CD_FRAMESIZE_RAW);
|
||||
else
|
||||
/* Got full amount, but now adjust size for jittering. */
|
||||
memcpy(p, p_buf+i_jitter_offset, i_sectors_orig*CDIO_CD_FRAMESIZE_RAW);
|
||||
|
||||
free(p_buf);
|
||||
return(i_sectors);
|
||||
}
|
||||
|
||||
/* read 'i_sector' adjacent audio sectors
|
||||
* into buffer '*p' beginning at sector 'begin'
|
||||
*/
|
||||
|
||||
static long int
|
||||
cooked_read (cdrom_drive_t *d, void *p, lsn_t begin, long i_sectors)
|
||||
{
|
||||
jitter_baddness_t jitter_badness = d->i_test_flags & 0x3;
|
||||
|
||||
/* read d->nsectors at a time, max. */
|
||||
i_sectors = ( i_sectors > d->nsectors && d->nsectors > 0 )
|
||||
? d->nsectors : i_sectors;
|
||||
|
||||
/* If we are testing under-run correction, we will deliberately set
|
||||
what we read a frame short. */
|
||||
if (d->i_test_flags & CDDA_TEST_UNDERRUN )
|
||||
i_sectors--;
|
||||
|
||||
if (jitter_badness) {
|
||||
return jitter_read(d, p, begin, i_sectors, jitter_badness);
|
||||
} else
|
||||
return read_blocks(d, p, begin, i_sectors);
|
||||
|
||||
}
|
||||
|
||||
/* hook */
|
||||
|
||||
@@ -847,7 +847,6 @@ main(int argc,char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
d->i_test_flags = test_flags;
|
||||
switch( cdda_open(d) ) {
|
||||
case -2:case -3:case -4:case -5:
|
||||
report("\nUnable to open disc. Is there an audio CD in the drive?");
|
||||
@@ -862,6 +861,8 @@ main(int argc,char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
d->i_test_flags = test_flags;
|
||||
|
||||
/* Dump the TOC */
|
||||
if (query_only || verbose ) display_toc(d);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# $Id: check_paranoia.sh.in,v 1.3 2005/01/15 16:05:44 rocky Exp $
|
||||
# $Id: check_paranoia.sh.in,v 1.4 2005/01/22 18:11:32 rocky Exp $
|
||||
# Compare our cd-paranoia with an installed cdparanoia
|
||||
|
||||
if test "@CMP@" != no -a "@BUILD_CD_PARANOIA_TRUE@"X = X ; then
|
||||
@@ -12,15 +12,23 @@ if test "@CMP@" != no -a "@BUILD_CD_PARANOIA_TRUE@"X = X ; then
|
||||
echo "** Raw cdda.bin extraction differ"
|
||||
exit 3
|
||||
fi
|
||||
../src/cd-paranoia/cd-paranoia -d ./cdda.cue -x 1 -v -r -- "1-"
|
||||
mv cdda.raw cdda-good.raw
|
||||
../src/cd-paranoia/cd-paranoia -d ./cdda.cue -x 64 -v -r -- "1-"
|
||||
mv cdda.raw cdda-underrun.raw
|
||||
../src/cd-paranoia/cd-paranoia -d ./cdda.cue -r -- "1-"
|
||||
if @CMP@ ./cdda-underrun.raw ./cdda.raw ; then
|
||||
if @CMP@ ./cdda-underrun.raw ./cdda-good.raw ; then
|
||||
echo "** Under-run correction okay"
|
||||
else
|
||||
echo "** Under-run correction problem"
|
||||
exit 3
|
||||
fi
|
||||
../src/cd-paranoia/cd-paranoia -d ./cdda.cue -x 5 -v -r -- "1-"
|
||||
if @CMP@ ./cdda-jitter.raw ./cdda-good.raw ; then
|
||||
echo "** Jitter correction okay"
|
||||
else
|
||||
echo "** Jitter correction problem"
|
||||
exit 3
|
||||
fi
|
||||
exit 0
|
||||
else
|
||||
echo "Don't see libcdio cd-paranoia program. Test skipped."
|
||||
|
||||
Reference in New Issue
Block a user