[paranoia] poor quality & glitches - all tracks on CD show unreported loss of streaming

Mikko Nummelin mnummeli at cc.hut.fi
Sat Oct 25 09:25:22 PDT 2003


On Sat, 25 Oct 2003, Adam Hardy wrote:

> I've not patched source code before - I got this error while trying to
> patch:
>
> [root at arnor adam]# patch -p0 <cdparanoia-III-alpha9.8/paranoia-patch
> patching file cdparanoia-III-alpha9.8/interface/cdda_interface.h
> Hunk #1 succeeded at 124 with fuzz 2 (offset -2 lines).
> patching file cdparanoia-III-alpha9.8/interface/interface.c
> Hunk #1 FAILED at 42.
> 1 out of 1 hunk FAILED -- saving rejects to file
> cdparanoia-III-alpha9.8/interface/interface.c.rej
> patching file cdparanoia-III-alpha9.8/interface/low_interface.h
> Hunk #1 FAILED at 65.
> 1 out of 1 hunk FAILED -- saving rejects to file
> cdparanoia-III-alpha9.8/interface/low_interface.h.rej
> patching file cdparanoia-III-alpha9.8/interface/scsi_interface.c
> patch: **** malformed patch at line 142: @@ -1432,7 +1510,10 @@

> Can you tell what I'm doing wrong? It seemed to have half worked.

This is due to the fact that if you just copy the patch from the page,
there might be some malformed newlines and extra whitespaces corrupting
the whole thing. I'll re-send it (or at least similarly working patch) now
as an attachment.

<p>Mikko Nummelin
-------------- next part --------------
diff -Nru cdparanoia-III-alpha9.8/interface/cdda_interface.h cdparanoia-III-alpha9.8P/interface/cdda_interface.h
--- cdparanoia-III-alpha9.8/interface/cdda_interface.h	2001-03-24 03:15:46.000000000 +0200
+++ cdparanoia-III-alpha9.8P/interface/cdda_interface.h	2003-03-15 18:07:43.000000000 +0200
@@ -126,7 +126,7 @@
 extern char *cdda_errors(cdrom_drive *d);
 
 extern int cdda_close(cdrom_drive *d);
-extern int cdda_open(cdrom_drive *d);
+extern int cdda_open(cdrom_drive *d, int protected);
 extern long cdda_read(cdrom_drive *d, void *buffer,
 		       long beginsector, long sectors);
 
diff -Nru cdparanoia-III-alpha9.8/interface/interface.c cdparanoia-III-alpha9.8P/interface/interface.c
--- cdparanoia-III-alpha9.8/interface/interface.c	2000-04-20 01:41:04.000000000 +0300
+++ cdparanoia-III-alpha9.8P/interface/interface.c	2003-03-15 18:07:43.000000000 +0200
@@ -42,13 +42,13 @@
 }
 
 /* finish initializing the drive! */
-int cdda_open(cdrom_drive *d){
+int cdda_open(cdrom_drive *d, int protected){
   int ret;
   if(d->opened)return(0);
 
   switch(d->interface){
   case GENERIC_SCSI:  
-    if((ret=scsi_init_drive(d)))
+    if((ret=scsi_init_drive(d, protected)))
       return(ret);
     break;
   case COOKED_IOCTL:  
diff -Nru cdparanoia-III-alpha9.8/interface/low_interface.h cdparanoia-III-alpha9.8P/interface/low_interface.h
--- cdparanoia-III-alpha9.8/interface/low_interface.h	2001-03-26 09:12:11.000000000 +0300
+++ cdparanoia-III-alpha9.8P/interface/low_interface.h	2003-03-15 18:07:43.000000000 +0200
@@ -65,7 +65,7 @@
 
 extern int  cooked_init_drive (cdrom_drive *d);
 extern unsigned char *scsi_inquiry (cdrom_drive *d);
-extern int  scsi_init_drive (cdrom_drive *d);
+extern int  scsi_init_drive (cdrom_drive *d, int protected);
 #ifdef CDDA_TEST
 extern int  test_init_drive (cdrom_drive *d);
 #endif
diff -Nru cdparanoia-III-alpha9.8/interface/scsi_interface.c cdparanoia-III-alpha9.8P/interface/scsi_interface.c
--- cdparanoia-III-alpha9.8/interface/scsi_interface.c	2001-03-24 03:15:46.000000000 +0200
+++ cdparanoia-III-alpha9.8P/interface/scsi_interface.c	2003-03-15 18:07:43.000000000 +0200
@@ -600,6 +600,84 @@
   return(tracks);
 }
 
+/* Yeah, it may be a crude hack. All at once is really the only way to go,
+   kernel ioctl way can be fooled by copy protections, i.e. corrupted TOCs.
+   So, we'll read the whole thing and scan for audio tracks. */
+
+static int scsi_read_toc_hack (cdrom_drive *d){
+    int i,first,last;
+    unsigned tracks;
+
+    /* READTOC, MSF format flag, res, res, res, res, Start track, len msb,
+       len lsb, flags */
+
+    /* read the whole freakin' TOC */
+    memcpy(d->sg_buffer, (char []){ 0x43, 0, 2, 0, 0, 0, 0, 8, 0, 0}, 10);
+    d->sg_buffer[1]=d->lun<<5;
+
+    if (handle_scsi_cmd (d,10, 0, 2048,'\377',1)){
+	cderror(d,"004: Unable to read table of contents header\n");
+	return(-4);
+    }
+
+    {
+	unsigned short len = *(d->sg_buffer)*256 + *(d->sg_buffer+1);
+	unsigned char *ptr = d->sg_buffer+4;
+	unsigned char flag, track;
+	unsigned int msf;
+	unsigned int leadout = 0;
+	unsigned char leadout_flag = 0;
+	first = 100;
+	last = 0;
+	while (ptr < d->sg_buffer+2+len)
+	{
+	    flag = *(ptr+1);
+	    track = *(ptr+3);
+	    if (track < 100)
+	    {
+		if (track < first)
+		    first = track;
+		else if (track > last)
+		    last = track;
+	    }
+	    ptr += 11;
+	}
+
+	tracks=last-first+1;
+
+	if (last > MAXTRK || first > MAXTRK || last<0 || first<0) {
+	    cderror(d,"003: CDROM reporting illegal number of tracks\n");
+	    return(-3);
+	}
+
+	ptr = d->sg_buffer+4;
+	while (ptr < d->sg_buffer+2+len)
+	{
+	    flag = *(ptr+1);
+	    track = *(ptr+3);
+	    msf = (*(ptr+8)*60 + *(ptr+9))*75 + *(ptr+10) - 150;
+	    if (track < 100)
+	    {
+		d->disc_toc[track-first].bFlags = flag;
+		d->disc_toc[track-first].bTrack = track;
+		d->disc_toc[track-first].dwStartSector = d->adjust_ssize * msf;
+	    }
+	    else if (track == 0xa2 && msf > leadout)
+	    {
+		leadout = msf;
+		leadout_flag = flag;
+	    }
+	    ptr += 11;
+	}
+	d->disc_toc[last-first+1].bFlags = leadout_flag;
+	d->disc_toc[last-first+1].bTrack = 0xAA;
+	d->disc_toc[last-first+1].dwStartSector = d->adjust_ssize * leadout;
+    }
+
+    d->cd_extra = FixupTOC(d,tracks+1); /* include lead-out */
+    return(tracks);
+}
+
 /* These do one 'extra' copy in the name of clean code */
 
 static int i_read_28 (cdrom_drive *d, void *p, long begin, long sectors){
@@ -1391,7 +1469,7 @@
 }
 
 
-int scsi_init_drive(cdrom_drive *d){
+int scsi_init_drive(cdrom_drive *d, int protected){
   int ret;
 
   check_atapi(d);
@@ -1432,7 +1510,10 @@
 					     sector size at 2048 to begin.*/
   d->enable_cdda(d,0);
 
-  d->read_toc = (!memcmp(d->drive_model, "IMS", 3) && !d->is_atapi) ? scsi_read_toc2 : 
+  if (protected)
+      d->read_toc = scsi_read_toc_hack;
+  else
+      d->read_toc = (!memcmp(d->drive_model, "IMS", 3) && !d->is_atapi) ? scsi_read_toc2 : 
     scsi_read_toc;
   d->set_speed = NULL;
   
@@ -1446,6 +1527,9 @@
       d->adjust_ssize = 1;
   }else
     d->adjust_ssize = 1;
+
+  if (protected)
+      d->read_audio = scsi_read_D8;
   
   d->tracks=d->read_toc(d);
   if(d->tracks<1)
diff -Nru cdparanoia-III-alpha9.8/main.c cdparanoia-III-alpha9.8P/main.c
--- cdparanoia-III-alpha9.8/main.c	2001-03-26 06:44:50.000000000 +0300
+++ cdparanoia-III-alpha9.8P/main.c	2003-03-15 18:07:43.000000000 +0200
@@ -275,7 +275,9 @@
 "                                    retries without progress.\n"
 "  -Z --disable-paranoia           : disable all paranoia checking\n"
 "  -Y --disable-extra-paranoia     : only do cdda2wav-style overlap checking\n"
-"  -X --abort-on-skip              : abort on imperfect reads/skips\n\n"
+"  -X --abort-on-skip              : abort on imperfect reads/skips\n"
+"  -P --protected                  : some workaround stuff for protected\n"
+"                                    discs (SCSI only)\n\n"
 
 "OUTPUT SMILIES:\n"
 "  :-)   Normal operation, low/no jitter\n"
@@ -585,7 +587,7 @@
     memset(dispcache,' ',graph);
 }
 
-const char *optstring = "escCn:o:O:d:g:S:prRwafvqVQhZz::YXWBi:Tt:";
+const char *optstring = "escCn:o:O:d:g:S:prRwafvqVQhZz::YXWBi:Tt:P";
 
 struct option options [] = {
 	{"stderr-progress",no_argument,NULL,'e'},
@@ -618,6 +620,7 @@
 	{"disable-fragmentation",no_argument,NULL,'F'},
 	{"output-info",required_argument,NULL,'i'},
 	{"never-skip",optional_argument,NULL,'z'},
+	{"protected",optional_argument,NULL,'P'},
 
 	{NULL,0,NULL,0}
 };
@@ -661,6 +664,7 @@
   int output_endian=0; /* -1=host, 0=little, 1=big */
   int query_only=0;
   int batch=0,i;
+  int protected=0;
 
   /* full paranoia, but allow skipping */
   int paranoia_mode=PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP; 
@@ -790,6 +794,9 @@
     case 'O':
       sample_offset=atoi(optarg);
       break;
+    case 'P':
+      protected = 1;
+      break;
     default:
       usage(stderr);
       exit(1);
@@ -896,7 +903,7 @@
     }
   }
 
-  switch(cdda_open(d)){
+  switch(cdda_open(d, protected)){
   case -2:case -3:case -4:case -5:
     report("\nUnable to open disc.  Is there an audio CD in the drive?");
     exit(1);


More information about the Paranoia mailing list