diff -u cdda2wav0.8/cdda2wav.c cdda2wav0.8-mmc/cdda2wav.c
--- cdda2wav0.8/cdda2wav.c	Fri Feb 28 14:39:06 1997
+++ cdda2wav0.8-mmc/cdda2wav.c	Tue Dec  2 16:32:16 1997
@@ -93,7 +93,7 @@
 unsigned char MD5_result[16];
 #endif
 
-const char * optstring = "D:A:I:O:c:b:r:a:t:i:d:o:n:v:"
+const char * optstring = "D:A:I:O:c:b:r:a:t:i:d:o:n:v:S:"
 #ifdef MD5_SIGNATURES
                          "M:"
 #endif
@@ -120,6 +120,7 @@
 	{"offset",required_argument,NULL,'o'},
 	{"sectors-per-request",required_argument,NULL,'n'},
 	{"verbose-level",required_argument,NULL,'v'},
+	{"speed",required_argument,NULL,'S'},
 #ifdef MD5_SIGNATURES
 	{"md5",required_argument,NULL,'M'},
 #endif
@@ -171,6 +172,7 @@
 int sh_bits;
 int channels = CHANNELS;
 int SkippedSamples = 0;
+int speed = 0;
 
 static char fname_base[200] = FILENAME;
 static long nSamplesToDo;
@@ -411,7 +413,7 @@
 "         [-t track] [-i index] [-o offset] [-d duration]\n"
 "         [-x] [-q] [-w] [-v] [-R] [-P] [-e] [-n sectors] [-N]\n"
 "         [-D device] [-I interface] [-O audiotype] [-B]\n"
-"         [-A auxdevice] [audiofile]\n"
+"         [-A auxdevice] [-S speed] [audiofile]\n"
 "Version "VERSION"\n"
 "cdda2wav copies parts from audio cd's directly to wav or au files.\n"
 "It requires a supported cdrom drive to work.\n"
@@ -436,6 +438,7 @@
 "         -O audiotype: set wav or sun or raw audio format. Default is wav.\n"
 "         -d duration : set recording time in seconds or 0 for whole track.\n"
 "         -B          : record each track into a seperate file.\n"
+"         -S mult     : set extraction speed to mult, 0 for maximum.\n"
 "         -w          : wait for audio signal, then start recording.\n"
 #ifdef	ECHO_TO_SOUNDCARD
 "         -e          : echo audio data to sound device SOUND_DEV.\n"
@@ -452,7 +455,7 @@
 #endif
 "defaults: %s, %d bit, %g Hz, track 1, no offset, one track,\n"
 "          type %s '%s', don't wait for signal, not quiet, not verbose,\n"
-"          use %s, device %s, aux %s\n"
+"          use %s, device %s, aux %s, max speed\n"
 "parameters: (optional) a file name or - for standard output.\n",
 	  CHANNELS-1?"stereo":"mono", BITS_P_S, 44100.0 / UNDERSAMPLING, 
           AUDIOTYPE, FILENAME, DEF_INTERFACE, CD_DEVICE, AUX_DEVICE);
@@ -573,6 +576,9 @@
 	break;	
       case 'v':    /* tell us more */
 	verbose = atoi( optarg );
+	break;
+      case 'S':    /* override speed */
+	speed = atoi( optarg );
 	break;
       case 'q':    /* be quiet */
 	quiet = 1;
--- cdda2wav0.8/interface.c	Sun Feb 23 05:28:02 1997
+++ cdda2wav0.8-mmc/interface.c	Tue Dec  2 18:00:43 1997
@@ -72,6 +72,8 @@
 unsigned nsectors = NSECTORS;
 unsigned overlap = 3;
 int lowendian = -1;
+extern int tracks;
+extern int speed;
 
 int trackindex_disp = FALSE;
 
@@ -195,6 +197,129 @@
 static unsigned char orgmode4 = 0xff;
 static unsigned char orgmode10, orgmode11;
 
+/* get CD capabilities page and determine whether drive supports MMC cmd set */
+/* returns 0 if not an MMC drive */
+/* returns 1 if an MMC drive which does not have the "CD-DA stream is accurate" bit set */
+/* returns 2 if an MMC drive which has the "CD-DA stream is accurate" bit set */
+
+static unsigned int 
+get_mmc(void)
+{
+      /* MODE_SENSE */
+      static unsigned char cmdblk0 [6] = { 
+	  0x1A, /* MODE_SENSE */
+	  0x00, /* return block descriptor */
+	  0x2A, /* CD capabilities and mechanical status page */
+	  0, /* reserved */
+	  22, /* sizeof(modesense - OFF) */
+	  0}; /* reserved */
+   
+      /* SET SPEED */
+      static unsigned char cmdblk1 [12] = {
+	  0xBB, /* SET SPEED */
+	  0, /* reserved */
+	  0, /* read speed MSB */
+	  0, /* read speed LSB */
+	  0, /* write speed MSB */
+	  0, /* write speed LSB */
+	  0, /* reserved */
+	  0, /* reserved */
+	  0, /* reserved */
+	  0, /* reserved */
+	  0, /* reserved */
+	  0}; /* reserved */
+   
+      static unsigned char modesense[MAXOFF+22]
+          __attribute__ ((aligned (__alignof__ (struct sg_header))));
+   
+      int base;
+      int ret = 0;
+      int spd, maxspd;
+      unsigned char *mode = cmd + OFF + 6;
+
+      memcpy( cmd + OFF, cmdblk0, sizeof(cmdblk0) );
+      memset(modesense, 0, sizeof modesense);
+      /* do the scsi cmd */
+      if (handle_scsi_cmd (6, 0, cmd, sizeof modesense - OFF, modesense, 1)) {
+	  perror ("get_mmc mode sense failed\n");
+	  return 0;
+      }
+   
+      if ((modesense[OFF] & 0x3F) == 0x2A) {
+	 base = OFF;
+      } else if ((modesense[OFF+12] & 0x3F) == 0x2A) {
+	 base = OFF+12;
+      } else {
+#ifdef NOTDEF
+	 printf("Can't find mode sense data for page 2A\n");
+#endif
+	 return 0;
+      }
+
+   printf("MMC data: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+	  modesense[base + 0], 
+	  modesense[base + 1],
+	  modesense[base + 2], 
+	  modesense[base + 3], 
+	  modesense[base + 4], 
+	  modesense[base + 5], 
+	  modesense[base + 6], 
+	  modesense[base + 7], 
+	  modesense[base + 8], 
+	  modesense[base + 9], 
+	  modesense[base + 10], 
+	  modesense[base + 11], 
+	  modesense[base + 12],
+	  modesense[base + 13], 
+	  modesense[base + 14], 
+	  modesense[base + 15], 
+	  modesense[base + 16], 
+	  modesense[base + 17], 
+	  modesense[base + 18], 
+	  modesense[base + 19], 
+	  modesense[base + 20], 
+	  modesense[base + 21]);
+
+      if ((modesense[base + 0] & 0x3F) == 0x2A &&
+	  modesense[base + 1] >= 5 &&
+	  (modesense[base + 5] & 0x01)) {
+	 if (modesense[base + 5] & 0x02) {
+	    printf("MMC command set drive, overlap processing is unnecessary\n");
+	    ret = 2;
+	 }
+	 printf("MMC command set drive, overlap processing may be required\n");
+	 ret = 1;
+      }
+      if (ret == 0) {
+#ifdef NOTDEF
+	 printf("Not an MMC audio-capable drive\n");
+#endif
+	 return 0;
+      }
+
+   memcpy( cmd + OFF, cmdblk1, sizeof(cmdblk1) );
+   maxspd = modesense[base + 8] * 256 + modesense[base + 9];
+   spd = modesense[base + 14] * 256 + modesense[base + 15];
+   printf ("Maximum read speed %d kB/sec\n", maxspd);
+   printf ("Current read speed %d kB/sec\n", spd);
+   if (speed == 0) {
+      spd = 0xFFFF;
+   } else {
+      spd = 176 * speed;
+      if (spd > maxspd) {
+	 spd = 0xFFFF;
+      }
+   }
+   cmd[OFF + 2] = spd / 256;
+   cmd[OFF + 3] = spd & 0xFF;
+   printf ("Setting read speed to %d kB/sec\n", spd == 0xFFFF ? maxspd : spd);
+   /* do the scsi cmd */
+   if (handle_scsi_cmd (12, 0, cmd, 0, NULL, 0)) {
+      perror ("get_mmc set speed failed\n");
+   }
+   return ret;
+}
+
 /* get current sector size from SCSI cdrom drive */
 static unsigned int 
 get_orig_sectorsize(unsigned char *m4, unsigned char *m10, 
@@ -342,6 +467,11 @@
 {
   int got, num_infos;
   unsigned char *Subp;
+   
+  if (pos + (length + CD_FRAMESIZE - 1) / CD_FRAMESIZE >= g_toc[tracks].dwStartSector) {
+     printf("Bogus CD Extra pointer, bailing\n");
+     return;
+  }
 
   Subp = alloca(length);
   if (Subp == NULL) {
@@ -649,6 +779,31 @@
     FatalError ("Read CD-ROM12 failed\n");
 }
 
+/* Read max. SectorBurst of cdda sectors to bufferCdda+OFF
+   via MMC standard READ CD command */
+static void ReadCddaMMC12 (unsigned char *p, long lSector, unsigned long SectorBurstVal )
+{
+  static unsigned char cmdblk [12] = {0xbe, 0x4, 0, 0, 0, 0, 0, 0, 0, 0xf0, 0, 0};
+
+  unsigned char *cmd0 = cmd + OFF;
+  int count = 3;
+
+  memcpy( cmd + OFF, cmdblk, sizeof(cmdblk) );
+
+  cmd0 [2] = (unsigned char)((lSector >> 24) & 0xFF);
+  cmd0 [3] = (unsigned char)((lSector >> 16) & 0xFF);
+  cmd0 [4] = (unsigned char)((lSector >> 8) & 0xFF);
+  cmd0 [5] = (unsigned char)(lSector & 0xFF);
+  cmd0 [8] = (unsigned char)SectorBurstVal;
+
+  while (handle_scsi_cmd(sizeof(cmdblk), 0, cmd, 
+			 SectorBurstVal * CD_FRAMESIZE_RAW, p - OFF, 0 )
+	 && count--)
+    ;
+  if (!count)
+    FatalError ("Read CD-ROMMMC12 failed\n");
+}
+
 /* Read the Sub-Q-Channel to SubQbuffer+OFF */
 static subq_chnl *ReadSubQSCSI ( unsigned char format, unsigned char track )
 {
@@ -767,50 +922,63 @@
 
 
      */
-    if (!memcmp(p+8,"TOSHIBA", 7) ||
-        !memcmp(p+8,"DEC", 3)) {
-	density = 0x82;
-	EnableCdda = EnableCddaModeSelect;
- 	ReadCdRom = ReadStandard;
-	lowendian = 1;
-    } else if (!memcmp(p+8,"IMS",3) ||
-               !memcmp(p+8,"KODAK",5) ||
-               !memcmp(p+8,"HP",2) ||
-               !memcmp(p+8,"PHILIPS",7) ||
-               !memcmp(p+8,"PLASMON",7) ||
-               !memcmp(p+8,"GRUNDIG CDR100IPW",17) ||
-               !memcmp(p+8,"MITSUMI CD-R ",13)) {
-	EnableCdda = EnableCddaModeSelect;
-	ReadCdRom = ReadStandard;
-
-	/* treat all of these as bigendian */
-	lowendian = 0;
-
-	/* no overlap reading for cd-writers */
-	overlap = 0;
-    } else if (!memcmp(p+8,"YAMAHA",6)) {
-	EnableCdda = EnableCddaModeSelect;
-
-	/* no overlap reading for cd-writers */
-	overlap = 0;
-	lowendian = 1;
-    } else if (!memcmp(p+8,"PLEXTOR",7) ||
-               !memcmp(p+8,"SONY",4)) {
-/*	overlap = 0; */
-	lowendian = 1;
-    } else if (!memcmp(p+8,"NEC",3)) {
-	ReadCdRom = ReadCdda10;
-	lowendian = 1;
-    }
-
-    ReadToc = ReadTocSCSI;
-    ReadSubQ = ReadSubQSCSI;
-
-    /* look if caddy is loaded */
-    while (!TestForMedium()) {
-	fprintf(stderr,"load cdrom please and press enter");
-	getchar();
+    switch (get_mmc()) {
+     case 2:
+       lowendian = 1;
+       overlap = 0;
+       break;
+     case 1:
+       lowendian = 1;
+       break;
+     case 0:
+       if (!memcmp(p+8,"TOSHIBA", 7) ||
+	   !memcmp(p+8,"DEC", 3)) {
+	  density = 0x82;
+	  EnableCdda = EnableCddaModeSelect;
+	  ReadCdRom = ReadStandard;
+	  lowendian = 1;
+       } else if (!memcmp(p+8,"IMS",3) ||
+		  !memcmp(p+8,"KODAK",5) ||
+		  !memcmp(p+8,"HP",2) ||
+		  !memcmp(p+8,"PHILIPS",7) ||
+		  !memcmp(p+8,"PLASMON",7) ||
+		  !memcmp(p+8,"GRUNDIG CDR100IPW",17) ||
+		  !memcmp(p+8,"MITSUMI CD-R ",13)) {
+	  EnableCdda = EnableCddaModeSelect;
+	  ReadCdRom = ReadStandard;
+	  
+	  /* treat all of these as bigendian */
+	  lowendian = 0;
+	  
+	  /* no overlap reading for cd-writers */
+	  overlap = 0;
+       } else if (!memcmp(p+8,"YAMAHA",6)) {
+	  EnableCdda = EnableCddaModeSelect;
+	  
+	  /* no overlap reading for cd-writers */
+	  overlap = 0;
+	  lowendian = 1;
+       } else if (!memcmp(p+8,"PLEXTOR",7) ||
+		  !memcmp(p+8,"SONY",4)) {
+	  /*	overlap = 0; */
+	  lowendian = 1;
+	  if (!memcmp(p+16, "CD-ROM CDU55E",13)) {
+	     ReadCdRom = ReadCddaMMC12;
+	  }
+       } else if (!memcmp(p+8,"NEC",3)) {
+	  ReadCdRom = ReadCdda10;
+	  lowendian = 1;
+       }
     }
+       
+   ReadToc = ReadTocSCSI;
+   ReadSubQ = ReadSubQSCSI;
+   
+   /* look if caddy is loaded */
+   while (!TestForMedium()) {
+      fprintf(stderr,"load cdrom please and press enter");
+      getchar();
+   }
 }
 
 /*******************************************************************
