⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdtester.c

📁 在linux下多媒体开发实例linux下多媒体开发
💻 C
字号:
/* * cdtester.c -- test the audio functions of a CD driver * * (c) 1995 Eberhard Moenkeberg <emoenke@gwdg.de> *          published under the GPL * *          made under heavy use of the "Tiny Audio CD Player" *          from Werner Zimmermann <zimmerma@rz.fht-esslingen.de> *          (see linux/drivers/block/README.aztcd) * *          Minor changes by Jeff Tranter to remove compile warnings * */#undef AZT_PRIVATE_IOCTLS /* not supported by every CDROM driver */#define SBP_PRIVATE_IOCTLS /* not supported by every CDROM driver */#include <sys/types.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <malloc.h>#include <ctype.h>#include <sys/ioctl.h>#include <linux/cdrom.h>#ifdef AZT_PRIVATE_IOCTLS#include <linux/aztcd.h>#endif AZT_PRIVATE_IOCTLS#ifdef SBP_PRIVATE_IOCTLS#include <linux/sbpcd.h>#include <linux/fs.h>#endif SBP_PRIVATE_IOCTLSstruct cdrom_tochdr hdr;struct cdrom_tochdr tocHdr;struct cdrom_tocentry TocEntry[101];struct cdrom_tocentry entry;struct cdrom_multisession ms_info;struct cdrom_read_audio read_audio;struct cdrom_ti ti;struct cdrom_subchnl subchnl;struct cdrom_msf msf;struct cdrom_volctrl volctrl;#ifdef AZT_PRIVATE_IOCTLSunion{  struct cdrom_msf msf;  unsigned char buf[CD_FRAMESIZE_RAW];} azt;#endif AZT_PRIVATE_IOCTLSint i, i1, i2, i3, j, k;unsigned char sequence=0;unsigned char command[80];unsigned char first=1, last=1;char *default_device="/dev/cdrom";char dev[20];char filename[20];int drive;int datafile;int rc;void help(void){  printf("Available Commands:\n");  printf("STOP          s      EJECT        e       QUIT         q\n");  printf("PLAY TRACK    t      PAUSE        p       RESUME       r\n");  printf("NEXT TRACK    n      REPEAT LAST  l       HELP         h\n");  printf("SUBCHANNEL_Q  c      TRACK INFO   i       PLAY AT      a\n");  printf("READ          d      READ RAW     w       READ AUDIO   A\n");  printf("MS-INFO       M      TOC          T       START        S\n");  printf("SET EJECTSW   X      DEVICE       D       DEBUG        Y\n");  printf("AUDIO_BUFSIZ  Z      RESET        R       BLKRASET     B\n");  printf("SET VOLUME    v      GET VOLUME   V\n");}/* *  convert MSF number (3 bytes only) to Logical_Block_Address  */int msf2lba(u_char *msf){  int i;	  i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;  if (i<0) return (0);  return (i);}/* *  convert logical_block_address to m-s-f_number (3 bytes only) */void lba2msf(int lba, unsigned char *msf){  lba += CD_BLOCK_OFFSET;  msf[0] = lba / (CD_SECS*CD_FRAMES);  lba %= CD_SECS*CD_FRAMES;  msf[1] = lba / CD_FRAMES;  msf[2] = lba % CD_FRAMES;}int init_drive(char *dev){  unsigned char msf_ent[3];    /*   * open the device   */  drive=open(dev,0);  if (drive<0) return (-1);  /*   * get TocHeader   */  printf("getting TocHeader...\n");  rc=ioctl(drive,CDROMREADTOCHDR,&hdr);  if (rc!=0)    {      printf("can't get TocHeader (error %d).\n",rc);      return (-2);    }  else    first=hdr.cdth_trk0;  last=hdr.cdth_trk1;  printf("TocHeader: %d %d\n",hdr.cdth_trk0,hdr.cdth_trk1);  /*   * get and display all TocEntries   */  printf("getting TocEntries...\n");  for (i=1;i<=hdr.cdth_trk1+1;i++)    {      if (i!=hdr.cdth_trk1+1) TocEntry[i].cdte_track = i;      else TocEntry[i].cdte_track = CDROM_LEADOUT;      TocEntry[i].cdte_format = CDROM_LBA;      rc=ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i]);      if (rc!=0)	{	  printf("can't get TocEntry #%d (error %d).\n",i,rc);	}      else	{	  lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);	  if (TocEntry[i].cdte_track==CDROM_LEADOUT)	    {	      printf("TocEntry #%02X: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",		     TocEntry[i].cdte_track,		     TocEntry[i].cdte_adr,		     TocEntry[i].cdte_ctrl,		     msf_ent[0],		     msf_ent[1],		     msf_ent[2],		     TocEntry[i].cdte_addr.lba,		     TocEntry[i].cdte_datamode);	    }	  else	    {	      printf("TocEntry #%02d: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",		     TocEntry[i].cdte_track,		     TocEntry[i].cdte_adr,		     TocEntry[i].cdte_ctrl,		     msf_ent[0],		     msf_ent[1],		     msf_ent[2],		     TocEntry[i].cdte_addr.lba,		     TocEntry[i].cdte_datamode);	    }	}    }  return (hdr.cdth_trk1); /* number of tracks */}void display(int size,unsigned char *buffer){  k=0;  getchar();  for (i=0;i<(size+1)/16;i++)    {      printf("%4d:",i*16);      for (j=0;j<16;j++)	{	  printf(" %02X",buffer[i*16+j]);	}      printf("  ");      for (j=0;j<16;j++)	{	  if (isalnum(buffer[i*16+j])) 	    printf("%c",buffer[i*16+j]);	  else	    printf(".");	}      printf("\n");       k++;      if (k>=20)	{	  printf("press ENTER to continue\n");	  getchar();	  k=0;	}    } } int main(){  printf("\nTesting tool for a CDROM driver's audio functions V0.1\n");  printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n");  printf("initializing...\n");    rc=init_drive(default_device);  if (rc<0) printf("could not open %s (rc=%d).\n",default_device,rc);  help();  while (1)    {      printf("Give a one-letter command (h = help): ");      scanf("%s",command);      command[1]=0;      switch (command[0])	{	case 'D':	  printf("device name (f.e. /dev/sbpcd3): ? ");	  scanf("%s",dev);	  close(drive);	  rc=init_drive(dev);	  if (rc<0) printf("could not open %s (rc %d).\n",dev,rc);	  break;	case 'e':	  rc=ioctl(drive,CDROMEJECT);	  if (rc<0) printf("CDROMEJECT: rc=%d.\n",rc);	  break;	case 'p':	  rc=ioctl(drive,CDROMPAUSE);	  if (rc<0) printf("CDROMPAUSE: rc=%d.\n",rc);	  break;	case 'r':	  rc=ioctl(drive,CDROMRESUME);	  if (rc<0) printf("CDROMRESUME: rc=%d.\n",rc);	  break;	case 's':	  rc=ioctl(drive,CDROMSTOP);	  if (rc<0) printf("CDROMSTOP: rc=%d.\n",rc);	  break;	case 'S':	  rc=ioctl(drive,CDROMSTART);	  if (rc<0) printf("CDROMSTART: rc=%d.\n",rc);	  break;	case 't':	  rc=ioctl(drive,CDROMREADTOCHDR,&tocHdr);	  if (rc<0)	    {	      printf("CDROMREADTOCHDR: rc=%d.\n",rc);	      break;	    }	  first=tocHdr.cdth_trk0;	  last= tocHdr.cdth_trk1;	  if ((first==0)||(first>last))	    {	      printf ("--got invalid TOC data.\n");	    }	  else	    {	      printf("--enter track number(first=%d, last=%d): ",first,last);	      scanf("%d",&i1);	      ti.cdti_trk0=i1;	      if (ti.cdti_trk0<first) ti.cdti_trk0=first;	      if (ti.cdti_trk0>last) ti.cdti_trk0=last;	      ti.cdti_ind0=0;	      ti.cdti_trk1=last;	      ti.cdti_ind1=0;	      rc=ioctl(drive,CDROMSTOP);	      rc=ioctl(drive,CDROMPLAYTRKIND,&ti);	      if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);	    }	  break;	case 'n':	  rc=ioctl(drive,CDROMSTOP);	  if (++ti.cdti_trk0>last) ti.cdti_trk0=last;	  ti.cdti_ind0=0;	  ti.cdti_trk1=last;	  ti.cdti_ind1=0;	  rc=ioctl(drive,CDROMPLAYTRKIND,&ti);	  if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);	  break;	case 'l':	  rc=ioctl(drive,CDROMSTOP);	  if (--ti.cdti_trk0<first) ti.cdti_trk0=first;	  ti.cdti_ind0=0;	  ti.cdti_trk1=last;	  ti.cdti_ind1=0;	  rc=ioctl(drive,CDROMPLAYTRKIND,&ti);	  if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);	  break;	case 'c':	  subchnl.cdsc_format=CDROM_MSF;	  rc=ioctl(drive,CDROMSUBCHNL,&subchnl);	  if (rc<0) printf("CDROMSUBCHNL: rc=%d.\n",rc);	  else	    {	      printf("AudioStatus:%s  Track:%d  Mode:%d  MSF=%02d:%02d:%02d\n",		     subchnl.cdsc_audiostatus==CDROM_AUDIO_PLAY ? "PLAYING":"NOT PLAYING",		     subchnl.cdsc_trk,subchnl.cdsc_adr, 		     subchnl.cdsc_absaddr.msf.minute,		     subchnl.cdsc_absaddr.msf.second,		     subchnl.cdsc_absaddr.msf.frame);	    }	  break;              	case 'i':	  printf("Track No.: ");	  scanf("%d",&i1);	  entry.cdte_track=i1;	  if (entry.cdte_track<first) entry.cdte_track=first;	  if (entry.cdte_track>last)  entry.cdte_track=last;	  entry.cdte_format=CDROM_MSF;	  rc=ioctl(drive,CDROMREADTOCENTRY,&entry);	  if (rc<0) printf("CDROMREADTOCENTRY: rc=%d.\n",rc);	  else	    {	      printf("Mode %d Track, starts at %02d:%02d:%02d\n",		     entry.cdte_adr,		     entry.cdte_addr.msf.minute,		     entry.cdte_addr.msf.second,		     entry.cdte_addr.msf.frame);	    }	  break;	case 'a':	  printf("Address (min:sec:frm)  ");	  scanf("%d:%d:%d",&i1,&i2,&i3);	  msf.cdmsf_min0=i1;	  msf.cdmsf_sec0=i2;	  msf.cdmsf_frame0=i3;	  if (msf.cdmsf_sec0>59) msf.cdmsf_sec0=59;	  if (msf.cdmsf_frame0>74) msf.cdmsf_frame0=74;	  lba2msf(TocEntry[last+1].cdte_addr.lba-1,&msf.cdmsf_min1);	  rc=ioctl(drive,CDROMSTOP);	  rc=ioctl(drive,CDROMPLAYMSF,&msf);	  if (rc<0) printf("CDROMPLAYMSF: rc=%d.\n",rc);	  break;#ifdef AZT_PRIVATE_IOCTLS /*not supported by every CDROM driver*/	case 'd':	  printf("Address (min:sec:frm)  ");	  scanf("%d:%d:%d",&i1,&i2,&i3);	  azt.msf.cdmsf_min0=i1;	  azt.msf.cdmsf_sec0=i2;	  azt.msf.cdmsf_frame0=i3;	  if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;	  if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;	  rc=ioctl(drive,CDROMREADMODE1,&azt.msf);	  if (rc<0) printf("CDROMREADMODE1: rc=%d.\n",rc);	  else display(CD_FRAMESIZE,azt.buf);	  break;	case 'w':	  printf("Address (min:sec:frame)  ");	  scanf("%d:%d:%d",&i1,&i2,&i3);	  azt.msf.cdmsf_min0=i1;	  azt.msf.cdmsf_sec0=i2;	  azt.msf.cdmsf_frame0=i3;	  if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;	  if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;	  rc=ioctl(drive,CDROMREADMODE2,&azt.msf);	  if (rc<0) printf("CDROMREADMODE2: rc=%d.\n",rc);	  else display(CD_FRAMESIZE_RAW,azt.buf); /* currently only 2336 */	  break;  #endif	case 'v':	  printf("--Channel 0 (Left)  (0-255): ");	  scanf("%d",&i1);	  volctrl.channel0=i1;	  printf("--Channel 1 (Right) (0-255): ");	  scanf("%d",&i1);	  volctrl.channel1=i1;	  volctrl.channel2=0;	  volctrl.channel3=0;	  rc=ioctl(drive,CDROMVOLCTRL,&volctrl);	  if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);	  break;  	case 'q':	  close(drive);	  exit(0);	case 'h':	  help();	  break;	case 'T': /* display TOC entry - without involving the driver */	  scanf("%d",&i);	  if ((i<hdr.cdth_trk0)||(i>hdr.cdth_trk1))	    printf("invalid track number.\n");	  else	    printf("TocEntry %02d: adr=%01X ctrl=%01X msf=%02d:%02d:%02d mode=%02X\n",		   TocEntry[i].cdte_track,		   TocEntry[i].cdte_adr,		   TocEntry[i].cdte_ctrl,		   TocEntry[i].cdte_addr.msf.minute,		   TocEntry[i].cdte_addr.msf.second,		   TocEntry[i].cdte_addr.msf.frame,		   TocEntry[i].cdte_datamode);	  break;	case 'A': /* read audio data into file */	  printf("Address (min:sec:frm) ? ");	  scanf("%d:%d:%d",&i1,&i2,&i3);	  read_audio.addr.msf.minute=i1;	  read_audio.addr.msf.second=i2;	  read_audio.addr.msf.frame=i3;	  read_audio.addr_format=CDROM_MSF;	  printf("# of frames ? ");	  scanf("%d",&i1);	  read_audio.nframes=i1;	  k=read_audio.nframes*CD_FRAMESIZE_RAW;	  read_audio.buf= (unsigned char*) malloc(k);	  if (read_audio.buf==NULL)	    {	      printf("can't malloc %d bytes.\n",k);	      break;	    }	  sprintf(filename,"audio_%02d%02d%02d_%02d.%02d",		  read_audio.addr.msf.minute,		  read_audio.addr.msf.second,		  read_audio.addr.msf.frame,		  read_audio.nframes,		  ++sequence);	  datafile=creat(filename, 0755);	  if (datafile<0)	    {	      printf("can't open datafile %s.\n",filename);	      break;	    }	  rc=ioctl(drive,CDROMREADAUDIO,&read_audio);	  if (rc!=0)	    {	      printf("CDROMREADAUDIO: rc=%d.\n",rc);	    }	  else	    {	      rc=write(datafile,&read_audio.buf,k);	      if (rc!=k) printf("datafile I/O error (%d).\n",rc);	    }	  close(datafile);	  break;	case 'X': /* set EJECT_SW (0: disable, 1: enable auto-ejecting) */	  scanf("%d",&i);	  rc=ioctl(drive,CDROMEJECT_SW,i);	  if (rc!=0)	    printf("CDROMEJECT_SW: rc=%d.\n",rc);	  else	    printf("EJECT_SW set to %d\n",i);	  break;	case 'M': /* get the multisession redirection info */	  ms_info.addr_format=CDROM_LBA;	  rc=ioctl(drive,CDROMMULTISESSION,&ms_info);	  if (rc!=0)	    {	      printf("CDROMMULTISESSION(lba): rc=%d.\n",rc);	    }	  else	    {	      if (ms_info.xa_flag) printf("MultiSession offset (lba): %d (0x%06X)\n",ms_info.addr.lba,ms_info.addr.lba);	      else		{		  printf("this CD is not an XA disk.\n");		  break;		}	    }	  ms_info.addr_format=CDROM_MSF;	  rc=ioctl(drive,CDROMMULTISESSION,&ms_info);	  if (rc!=0)	    {	      printf("CDROMMULTISESSION(msf): rc=%d.\n",rc);	    }	  else	    {	      if (ms_info.xa_flag)		printf("MultiSession offset (msf): %02d:%02d:%02d (0x%02X%02X%02X)\n",		       ms_info.addr.msf.minute,		       ms_info.addr.msf.second,		       ms_info.addr.msf.frame,		       ms_info.addr.msf.minute,		       ms_info.addr.msf.second,		       ms_info.addr.msf.frame);	      else printf("this CD is not an XA disk.\n");	    }	  break;#ifdef SBP_PRIVATE_IOCTLS	case 'Y': /* set the driver's message level */#if 0 /* not implemented yet */	  printf("enter switch name (f.e. DBG_CMD): ");	  scanf("%s",&dbg_switch);	  j=get_dbg_num(dbg_switch);#else	  printf("enter DDIOCSDBG switch number: ");	  scanf("%d",&j);#endif	  printf("enter 0 for \"off\", 1 for \"on\": ");	  scanf("%d",&i);	  if (i==0) j|=0x80;	  printf("calling \"ioctl(drive,DDIOCSDBG,%d)\"\n",j);	  rc=ioctl(drive,DDIOCSDBG,j);	  printf("DDIOCSDBG: rc=%d.\n",rc);	  break;	case 'Z': /* set the audio buffer size */	  printf("# frames wanted: ? ");	  scanf("%d",&j);	  rc=ioctl(drive,CDROMAUDIOBUFSIZ,j);	  printf("%d frames granted.\n",rc);	  break;	case 'V':	  rc=ioctl(drive,CDROMVOLREAD,&volctrl);	  if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);	  printf("Volume: channel 0 (left) %d, channel 1 (right) %d\n",volctrl.channel0,volctrl.channel1);	  break;  	case 'R':	  rc=ioctl(drive,CDROMRESET);	  if (rc<0) printf("CDROMRESET: rc=%d.\n",rc);	  break;	case 'B': /* set the driver's (?) read ahead value */	  printf("enter read-ahead size: ? ");	  scanf("%d",&i);	  rc=ioctl(drive,BLKRASET,i);	  if (rc<0) printf("BLKRASET: rc=%d.\n",rc);	  break;#endif SBP_PRIVATE_IOCTLS	default:	  printf("unknown command: \"%s\".\n",command);	  break;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -