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

📄 sbpcd

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻
📖 第 1 页 / 共 3 页
字号:
Once activated, it does not stop before success or end-of-list. This may beuseful within "universal" CDROM installation boot floppies (but using the loadable module would be better because it allows an "extended" auto-probingwithout fearing NE2000 cards).To shorten the auto-probing list to a single entry, set DISTRIBUTION 0 withinsbpcd.h.Setting up address and interface type:--------------------------------------If your I/O port address is not 0x340, you have to look for the #defines nearthe beginning of sbpcd.h and configure them: set SBPRO to 0 or 1 or 2, andchange CDROM_PORT to the address of your CDROM I/O port.Almost all of the "SoundBlaster compatible" cards behave like the no-soundinterfaces, i.e. need SBPRO 0! With "original" SB Pro cards, an initial setting of CD_volume through thesound card's MIXER register gets done.If you are using a "compatible" sound card of types "LaserMate" or "SPEA",you can set SOUND_BASE (in sbpcd.h) to get it done with your card, too...Using audio CDs:----------------Workman, WorkBone, xcdplayer, cdplayer and the nice little tool "cdplay" (seeREADME.aztcd from the Aztech driver package) should work.The program CDplayer likes to talk to "/dev/mcd" only, xcdplayer wants"/dev/rsr0", workman loves "/dev/sr0" or "/dev/cdrom" - so, make the appropriate links to use them without the need to supply parameters.Copying audio tracks:---------------------The following program will copy track 1 (or a piece of it) from an audio CDinto the file "track01":/*=================== begin program ========================================*//* * read an audio track from a CD * * (c) 1994 Eberhard Moenkeberg <emoenke@gwdg.de> *          may be used & enhanced freely * * Due to non-existent sync bytes at the beginning of each audio frame (or due * to a firmware bug within all known drives?), it is currently a kind of * fortune if two consecutive frames fit together. * Usually, they overlap, or a little piece is missing. This happens in units * of 24-byte chunks. It has to get fixed by higher-level software (reading * until an overlap occurs, and then eliminate the overlapping chunks).  * ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz holds an example of * such an algorithm. * This example program further is missing to obtain the SubChannel data * which belong to each frame. * * This is only an example of the low-level access routine. The read data are * pure 16-bit CDDA values; they have to get converted to make sound out of * them. * It is no fun to listen to it without prior overlap/underlap correction! */#include <stdio.h>#include <sys/ioctl.h>#include <linux/cdrom.h>static struct cdrom_tochdr hdr;static struct cdrom_tocentry entry[101];static struct cdrom_read_audio arg;static u_char buffer[CD_FRAMESIZE_RAW];static int datafile, drive;static int i, j, limit, track, err;static char filename[32];main(int argc, char *argv[]){/* * open /dev/cdrom */  drive=open("/dev/cdrom", 0);  if (drive<0)    {      fprintf(stderr, "can't open drive.\n");      exit (-1);    }/* * get TocHeader */  fprintf(stdout, "getting TocHeader...\n");  err=ioctl(drive, CDROMREADTOCHDR, &hdr);  if (err!=0)    {      fprintf(stderr, "can't get TocHeader (error %d).\n", err);      exit (-1);    }  else    fprintf(stdout, "TocHeader: %d %d\n", hdr.cdth_trk0, hdr.cdth_trk1);/* * get and display all TocEntries */  fprintf(stdout, "getting TocEntries...\n");  for (i=1;i<=hdr.cdth_trk1+1;i++)    {      if (i!=hdr.cdth_trk1+1) entry[i].cdte_track = i;      else entry[i].cdte_track = CDROM_LEADOUT;      entry[i].cdte_format = CDROM_LBA;      err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]);      if (err!=0)	{	  fprintf(stderr, "can't get TocEntry #%d (error %d).\n", i, err);	  exit (-1);	}      else	{	  fprintf(stdout, "TocEntry #%d: %1X %1X %06X %02X\n",		 entry[i].cdte_track,		 entry[i].cdte_adr,		 entry[i].cdte_ctrl,		 entry[i].cdte_addr.lba,		 entry[i].cdte_datamode);	}    }  fprintf(stdout, "got all TocEntries.\n");/* * ask for track number (not implemented here) */track=1;#if 0 /* just read a little piece (4 seconds) */entry[track+1].cdte_addr.lba=entry[track].cdte_addr.lba+300;#endif/* * read track into file */  sprintf(filename, "track%02d\0", track);  datafile=creat(filename, 0755);  if (datafile<0)    {      fprintf(stderr, "can't open datafile %s.\n", filename);      exit (-1);    }  arg.addr.lba=entry[track].cdte_addr.lba;  arg.addr_format=CDROM_LBA; /* CDROM_MSF would be possible here, too. */  arg.nframes=1;  arg.buf=&buffer[0];  limit=entry[track+1].cdte_addr.lba;  for (;arg.addr.lba<limit;arg.addr.lba++)    {      err=ioctl(drive, CDROMREADAUDIO, &arg);      if (err!=0)	{	  fprintf(stderr, "can't read abs. frame #%d (error %d).\n", 		 arg.addr.lba, err);	}      j=write(datafile, &buffer[0], CD_FRAMESIZE_RAW);      if (j!=CD_FRAMESIZE_RAW)	{	  fprintf(stderr,"I/O error (datafile) at rel. frame %d\n",			 arg.addr.lba-entry[track].cdte_addr.lba);	}      arg.addr.lba++;    }}/*===================== end program ========================================*/At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz is an adapted version ofHeiko Eissfeldt's digital-audio to .WAV converter (the original is there, too).This is preliminary, as Heiko himself will care about it.Known problems:---------------Currently, the detection of disk change or removal is actively disabled.Most attempts to read the UPC/EAN code result in a stream of zeroes. All mydrives are mostly telling there is no UPC/EAN code on disk or there is, but itis an all-zero number. I guess now almost no CD holds such a number.Bug reports, comments, wishes, donations (technical information is a donation,too :-) etc. to emoenke@gwdg.de.SnailMail address, preferable for CD editors if they want to submit a free"cooperation" copy:                         Eberhard Moenkeberg                         Reinholdstr. 14                         D-37083 Goettingen                         Germany---Appendix -- the "cdtester" utility:/* * 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) */#undef AZT_PRIVATE_IOCTLS /* not supported by every CDROM driver */#define SBP_PRIVATE_IOCTLS /* not supported by every CDROM driver */#include <stdio.h>#include <stdio.h>#include <malloc.h>#include <sys/ioctl.h>#include <linux/cdrom.h>#ifdef AZT_PRIVATE_IOCTLS#include <linux/../../drivers/cdrom/aztcd.h>#endif AZT_PRIVATE_IOCTLS#ifdef SBP_PRIVATE_IOCTLS#include <linux/../../drivers/cdrom/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 */}

⌨️ 快捷键说明

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