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

📄 read_cdda.c

📁 读取音乐光盘磁道为磁盘文件的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
intcdda_init(unsigned char **bufadr, unsigned char **bufadr2, long *buflen, char *device){  int fd;  struct cdrom_cdda cdda;    *bufadr = malloc(NUM_BLOCKS * CDDA_BLKSIZE);  *bufadr2 = malloc(NUM_BLOCKS * CDDA_BLKSIZE);     if(*bufadr == NULL || *bufadr2 == NULL)    pop_error(ERR_MALLOC, "Malloc of buffer failed");  *buflen = NUM_BLOCKS * CDDA_BLKSIZE;  /* open the device */  if(device != NULL)    fd = open(device, 0);  else {    fd = open("/dev/rdsk/c0t6d0s2", 0);    if(fd < 0)      fd = open("/vol/dev/aliases/cdrom0", 0);  }  if(fd < 0)    pop_error(ERR_FILE, "Open of CD-ROM device failed");    cdda.cdda_addr = 200;  cdda.cdda_length = 1;  cdda.cdda_data = *bufadr;  cdda.cdda_subcode = CDROM_DA_NO_SUBCODE;    if(ioctl(fd, CDROMCDDA, &cdda) < 0)    pop_error(ERR_GEN, "Error initializing CD-ROM DA");    return fd;}/* * Reads a bunch of data from the cdrom returning the number of * bytes read.  To do jitter control we always re-read 7 extra  * block from the cd.  Next time around we compare the first * block read to the previous last block, adjusting +- bytes * * eg: * first read: (writing out all blocks 1->n) * |------||------||------||------||------| *   blk 1  blk 2    ...            blk n * next read: *                                 |------||------||------||------| *                                  blk n   blk n+1  ... * ideally the last CDDABLKSIZE bytes of the old buffer would match * exactly with the first CDDABLKSIZE bytes of the new buffer and we * would write out from newbuffer+CDDABLKSIZE.  But because of jitter * the usually won't so we write out a little bit more or less. */longcdda_read(int fd, unsigned char *rawbuf, int to_read, int addr){  struct cdrom_cdda cdda;    cdda.cdda_addr = addr;  cdda.cdda_length = to_read;  cdda.cdda_data = rawbuf;  cdda.cdda_subcode = CDROM_DA_NO_SUBCODE;    if(ioctl(fd, CDROMCDDA, &cdda) < 0)    {      if(errno == ENXIO)	{	  pop_error(NO_ERR, "CD has been ejected\n");	  return -1;	}            if(ioctl(fd, CDROMCDDA, &cdda) < 0)	{	  if(ioctl(fd, CDROMCDDA, &cdda) < 0)	    {	      if(ioctl(fd, CDROMCDDA, &cdda) < 0)		{		  pop_error(NO_ERR, "CDROM CDDA failed\n");		  return -1;		}	    }	}    }    return (cdda.cdda_length);}/* * Write out the data */voidcdda_write(int fd, unsigned char *buf, long len, boolean swap, int fmt){  int blocks = len / CDDA_BLKSIZE, ctr, ctr2;  int write_len = SAMPLES_PER_BLK * 2 * 2;   /* i.e. 2352 */  unsigned char *outbuf = NULL, *ptr;  if(outbuf == NULL)    outbuf = malloc(CDDA_BLKSIZE + 1);  for(ctr = 0; ctr < blocks; ctr++)    {      ptr = outbuf;            /* if they want swapping then we don't swap - make sense? */      if(!swap)	{	  for(ctr2 = 0; ctr2 < SAMPLES_PER_BLK * 2; ctr2++)	    {	      *(ptr+1) = *buf++;	      *ptr = *buf++;	      ptr += 2;	    }	}      if(fmt == AU8)	write_len = convert(outbuf);            write(fd, outbuf, write_len);    }}/* * Read the Table of Contents */intread_toc(int fd, boolean toc){  int ctr, prev_time, start_sec;  struct cdrom_tochdr hdr;  struct cdrom_tocentry entry;    if(ioctl(fd, CDROMREADTOCHDR, &hdr) < 0)    pop_error(ERR_GEN, "Error getting TOC header from CD");    if(ioctl(fd, CDROMSBLKMODE, CDDA_BLKSIZE) < 0)    fprintf(stderr,  "Unable to set blocksize, continuing anyways...");    if(verbose)    fprintf(stderr, "Number of tracks %d\n", hdr.cdth_trk1);  prev_time = 0;  for(ctr = 1; ctr <= hdr.cdth_trk1; ctr++)    {      entry.cdte_track = ctr;      entry.cdte_format = CDROM_MSF;            if(ioctl(fd, CDROMREADTOCENTRY, &entry) < 0)	pop_error(ERR_GEN, "Error getting TOC entry from CD");        tracks[ctr].mins = entry.cdte_addr.msf.minute;      tracks[ctr].secs = entry.cdte_addr.msf.second;      tracks[ctr].frames = entry.cdte_addr.msf.frame;      start_sec = entry.cdte_addr.msf.minute * 60 + entry.cdte_addr.msf.second;            entry.cdte_format = CDROM_LBA;            if(ioctl(fd, CDROMREADTOCENTRY, &entry) < 0)	pop_error(ERR_GEN, "Error getting TOC entry from CD");      tracks[ctr].start_block = entry.cdte_addr.lba;      if(ctr != 1)	{	  tracks[ctr - 1].num_blocks = tracks[ctr].start_block - tracks[ctr - 1].start_block;	  tracks[ctr - 1].length =  start_sec - prev_time;	}      prev_time = start_sec;    }    /* get last lba */    entry.cdte_track = CDROM_LEADOUT;  entry.cdte_format = CDROM_MSF;  if(ioctl(fd, CDROMREADTOCENTRY, &entry) < 0)    pop_error(ERR_GEN, "Error getting TOC entry from CD");      start_sec = entry.cdte_addr.msf.minute * 60 + entry.cdte_addr.msf.second;  entry.cdte_track = CDROM_LEADOUT;  entry.cdte_format = CDROM_LBA;    if(ioctl(fd, CDROMREADTOCENTRY, &entry) < 0)    pop_error(ERR_GEN, "Error getting TOC entry from CD");      tracks[ctr - 1].num_blocks = entry.cdte_addr.lba - tracks[ctr - 1].start_block;  tracks[ctr - 1].length = start_sec - prev_time;  /* if needed print out info */  if(verbose)    {      for(ctr = 1; ctr <= hdr.cdth_trk1; ctr++)	{      	  fprintf(stderr, "Track %02d: Start: %02d:%02d:%02d  Length: %02d:%02d  %3.2f MB  lba: %d/%d\n", ctr,		  tracks[ctr].mins, tracks[ctr].secs, tracks[ctr].frames,		  tracks[ctr].length / 60, tracks[ctr].length % 60,		  (double) tracks[ctr].num_blocks * CDDA_BLKSIZE / (1024 * 1024),		  tracks[ctr].start_block,		  tracks[ctr].num_blocks);	}    }  return hdr.cdth_trk1;}/* *  write_sun_header - Write sun .au fmt type header */voidwrite_sun_header(int fd, int fmt){  int wrote, val;  typedef unsigned long	u_32;  struct auheader {    u_32 magic;    u_32 hdr_size;    u_32 data_size;    u_32 encoding;    u_32 sample_rate;    u_32 channels;  } hdr;    /* initialize ulaw mappings */  ulawmap = (unsigned char *) malloc(65536);  if(ulawmap == NULL)    pop_error(ERR_MALLOC, "Error mallocing memory for ulawmap");  for(val = 0; val < 65536; val++)    ulawmap[val] = linear_to_ulaw(val - 32768);  ulawmap += 32768;  hdr.magic = 0x2e736e64;  hdr.hdr_size = sizeof(hdr) + 28;  hdr.data_size = (fmt == AU16) ? 16 : 8;  hdr.encoding = (fmt == AU16) ? 3 : 1;  hdr.sample_rate = (fmt == AU16) ? 44100 : 8000;  hdr.channels = (fmt == AU16) ? 2 : 1;   wrote = write(fd, &hdr, sizeof(hdr));  if(wrote != sizeof(hdr))    pop_error(ERR_FILE, "Error writing to output file");  wrote = write(fd, "Recorded from CD by Read_CDDA", 28);  if(wrote != 28)    pop_error(ERR_FILE, "Error writing to output file");}intconvert(unsigned char *buf){  short *buf16 = (short *) buf;  int ctr, ctr2, samples;  int mono_value;  unsigned char *bufend = buf + SAMPLES_PER_BLK * 4;      for(ctr = 0; buf16 < (short *)(bufend); ctr++)    {      samples = (ctr & 1) ? ((ctr % 20) ? 10 : 12) : 12;            if(buf16 + samples > (short *)(bufend))	samples = ((short *)bufend) - buf16;           mono_value = 0;      for(ctr2 = 0; ctr2 < samples; ctr2++)	mono_value += *buf16++;      mono_value /= samples;      buf[ctr] = ulawmap[mono_value];    }    return ctr;}/* *  usage - Print out some command line help */voidusage(char *prog_name){  fprintf(stderr, "%s: Read audio track from CD to a file\n", prog_name);  fprintf(stderr, "Written by Jim Mintha (mintha@geog.ubc.ca)\n");  fprintf(stderr, "Usage: %s [-h] [-a] [-8] [-d] [-t] [-D dev] [-s start] [-e end] track [outfile]\n", prog_name);  fprintf(stderr, " track           Track number to read\n");  fprintf(stderr, " outfile         File name for PCM or .au output (\"-\" for stdout)\n");  fprintf(stderr, " -s  --start     Starting second for the track\n");  fprintf(stderr, " -e  --end       Ending second for the track\n");  fprintf(stderr, " -t  --toc       Only print out the Table of Contents\n");  fprintf(stderr, " -x  --swap      Swap bytes (for x86?)\n");  fprintf(stderr, " -8  --au8       Output in Sun .au format 8KHz\n");  fprintf(stderr, " -a  --au16      Output in Sun .au format 44.1KHz\n");  fprintf(stderr, " -b  --buffer    Size of read-ahead buffer\n");  fprintf(stderr, " -v  --verbose   Be talkative while running\n");  fprintf(stderr, " -d  --drvtype   Print CD-ROM model type only\n");  fprintf(stderr, " -D  --device    Device to read from\n");  /*  fprintf(stderr, " -W  --whole     Extract all tracks to [outfile].[t#]\n");*/  fprintf(stderr, " -V  --version   Print program version number only\n\n");  fprintf(stderr, " Default is to output in CDR format the whole track\n");  exit(0);}/* * all-done - Reset the blocksize and finish */voidall_done(int fd){  /* reset block size on cdrom */  if(ioctl(fd, CDROMSBLKMODE, 512) < 0)    fprintf(stderr, "Unable to reset blocksize");  close(fd);  exit(0);}/*** This routine converts from linear to ulaw.**** Craig Reese: IDA/Supercomputing Research Center** Joe Campbell: Department of Defense** 29 September 1989**** References:** 1) CCITT Recommendation G.711  (very difficult to follow)** 2) "A New Digital Technique for Implementation of Any**     Continuous PCM Companding Law," Villeret, Michel,**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,**     1973, pg. 11.12-11.17** 3) MIL-STD-188-113,"Interoperability and Performance Standards**     for Analog-to_Digital Conversion Techniques,"**     17 February 1987**** Input: Signed 16 bit linear sample** Output: 8 bit ulaw sample*/#define ZEROTRAP    /* turn on the trap as per the MIL-STD */#define BIAS 0x84               /* define the add-in bias for 16 bit samples */#define CLIP 32635 unsigned charlinear_to_ulaw( sample )int sample;{	static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,				   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,				   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,				   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,				   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,				   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};	int sign, exponent, mantissa;	unsigned char ulawbyte; 	/* Get the sample into sign-magnitude. */	sign = (sample >> 8) & 0x80;            /* set aside the sign */	if ( sign != 0 ) sample = -sample;              /* get magnitude */	if ( sample > CLIP ) sample = CLIP;             /* clip the magnitude */ 	/* Convert from 16 bit linear to ulaw. */	sample = sample + BIAS;	exponent = exp_lut[( sample >> 7 ) & 0xFF];	mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;	ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );#ifdef ZEROTRAP	if ( ulawbyte == 0 ) ulawbyte = 0x02;   /* optional CCITT trap */#endif 	return ulawbyte;}

⌨️ 快捷键说明

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