Add jitter simulation and jitter-correction testing.

This commit is contained in:
rocky
2005-01-22 18:11:32 +00:00
parent 4e8d4c1373
commit 567e6e7775
4 changed files with 153 additions and 36 deletions

View File

@@ -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) 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Xiph.org 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
/** jitter testing. The first two bits are set to determine the byte-distance we will jitter the data; 0 is no shifting.
how much jitter to simulate.
*/ */
#define CDDA_TEST_JITTER_SMALL 1 #define CDDA_TEST_JITTER_SMALL 1
#define CDDA_TEST_JITTER_LARGE 2 #define CDDA_TEST_JITTER_LARGE 2
#define CDDA_TEST_JITTER_MASSIVE 3 #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 */ /** fragment testing */
#define CDDA_TEST_FRAG_SMALL (1<<2) #define CDDA_TEST_FRAG_SMALL (1<<3)
#define CDDA_TEST_FRAG_LARGE (2<<2) #define CDDA_TEST_FRAG_LARGE (2<<3)
#define CDDA_TEST_FRAG_MASSIVE (3<<2) #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 */ /** scratch testing */
#define CDDA_TEST_SCRATCH 32 #define CDDA_TEST_SCRATCH 128
#undef CDDA_TEST_BOGUS_BYTES 64 #undef CDDA_TEST_BOGUS_BYTES 256
#undef CDDA_TEST_DROPDUPE_BYTES 128 #undef CDDA_TEST_DROPDUPE_BYTES 512
#endif /* TESTING_IS_FINISHED */ #endif /* TESTING_IS_FINISHED */
/** autosense functions */ /** autosense functions */

View File

@@ -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> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
Original interface.c Copyright (C) 1994-1997 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); return cdio_set_speed(d->p_cdio, i_speed);
} }
/* read 'SectorBurst' adjacent sectors of audio sectors /* read 'i_sector' adjacent audio sectors
* to Buffer '*p' beginning at sector 'lSector' * into buffer '*p' beginning at sector 'begin'
*/ */
static long int 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; 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 { 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 ( 0 != err ) {
if (!d->error_retry) return -7; 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 /* *Could* be I/O or media error. I think. If we're at
30 retries, we better skip this unhappy little 30 retries, we better skip this unhappy little
sector. */ sector. */
@@ -111,8 +102,8 @@ cooked_read (cdrom_drive_t *d, void *p, lsn_t begin, long sectors)
} }
if(retry_count>4) if(retry_count>4)
if(sectors>1) if(i_sectors>1)
sectors=sectors*3/4; i_sectors=i_sectors*3/4;
retry_count++; retry_count++;
if (retry_count>MAX_RETRIES) { if (retry_count>MAX_RETRIES) {
cderror(d,"007: Unknown, unrecoverable error reading data\n"); 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; break;
} while (err); } 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 */ /* hook */

View File

@@ -847,7 +847,6 @@ main(int argc,char *argv[])
} }
} }
d->i_test_flags = test_flags;
switch( cdda_open(d) ) { switch( cdda_open(d) ) {
case -2:case -3:case -4:case -5: case -2:case -3:case -4:case -5:
report("\nUnable to open disc. Is there an audio CD in the drive?"); report("\nUnable to open disc. Is there an audio CD in the drive?");
@@ -862,6 +861,8 @@ main(int argc,char *argv[])
exit(1); exit(1);
} }
d->i_test_flags = test_flags;
/* Dump the TOC */ /* Dump the TOC */
if (query_only || verbose ) display_toc(d); if (query_only || verbose ) display_toc(d);

View File

@@ -1,5 +1,5 @@
#!/bin/sh #!/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 # Compare our cd-paranoia with an installed cdparanoia
if test "@CMP@" != no -a "@BUILD_CD_PARANOIA_TRUE@"X = X ; then 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" echo "** Raw cdda.bin extraction differ"
exit 3 exit 3
fi 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 mv cdda.raw cdda-underrun.raw
../src/cd-paranoia/cd-paranoia -d ./cdda.cue -r -- "1-" ../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" echo "** Under-run correction okay"
else else
echo "** Under-run correction problem" echo "** Under-run correction problem"
exit 3 exit 3
fi 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 exit 0
else else
echo "Don't see libcdio cd-paranoia program. Test skipped." echo "Don't see libcdio cd-paranoia program. Test skipped."