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) 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 */
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
Reference in New Issue
Block a user