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

📄 cddev.c

📁 mcdp 是一个的型的Linux下的CD播放器
💻 C
字号:
/* * Author strongly advices against using this code, or a part of it, * in an application designed to run on any Microsoft(tm) platform. * * See doc/README for more information about COPYING terms. */#include "mcd.h"short cddb; /* if 0, we have no entries and no remote stuff */static void cd_playmsf(struct mcd *cd, struct cdrom_msf *msf);static void cd_playmsf(struct mcd *cd, struct cdrom_msf *msf) { if (cd->status == CDROM_AUDIO_PLAY)  if (ioctl(cd->fd,CDROMPAUSE,NULL)<0)   return; if (ioctl(cd->fd,CDROMPLAYMSF, msf)<0)  draw_status("error playing",1); return;}/* GLOBAL *//* look at the specs, should do, what they want :) */unsigned cd_discid(struct mcd *cd) { static unsigned cd_cddbsum(register int n) {  register unsigned int ret=0;  while (n>0) {   ret += (n%10); n /= 10;  }  return ret; } unsigned int i=1, n=0; while (i<=cd->title[1]) {  n+=cd_cddbsum(cd->t[i].cddb/75);i++; } return ((n%0xff)<<24|(cd->t[0].cddb - cd->t[1].cddb/75)<<8|cd->title[1]);}/* open device or exit ! */int cd_init(const char *cdpath, struct mcd *cd) { cd->fd=open(cdpath,O_RDONLY|O_NONBLOCK); if ((cd->fd<0) || (cd->status=ioctl(cd->fd,CDROM_DISC_STATUS,NULL)<0)) {  _printf("Sorry, can't open cd-device \"%s\" !\n",cdpath);  exit(1); } if (cd->status==(100||105)) return -1; /* audio/mixed */ return 0;}/* needs correct cd->fd; seems very efficient (no division...) */int cd_readtracks(struct mcd *cd) { struct cdrom_tochdr cdth;        /* TocHdr Stuff */ register int i; if (ioctl(cd->fd, CDROMREADTOCHDR, &cdth)<0) {  draw_status("can't read disc",1);  return -1; } /* track[1] - [last-1])*/ for (i=1;i<=cdth.cdth_trk1 && i<=MCD_CDAUDIO_MAX;i++) {  cd->cdte[i].cdte_track=i;  cd->cdte[i].cdte_format=CDROM_MSF;  if (ioctl(cd->fd, CDROMREADTOCENTRY, &cd->cdte[i])<0)   return -1;  else {   cd->t[i].audio=cd->cdte[i].cdte_ctrl & CDROM_DATA_TRACK;   cd->t[i].min=cd->cdte[i].cdte_addr.msf.minute;   cd->t[i].sec=cd->cdte[i].cdte_addr.msf.second;   cd->t[i].cddb = cd->cdte[i].cdte_addr.msf.minute*60*75 +     cd->cdte[i].cdte_addr.msf.second*75 +     cd->cdte[i].cdte_addr.msf.frame; /* cddb[track] */   cd->t[i-1].min=cd->t[i].min-cd->t[i-1].min;   if ((cd->cdte[i].cdte_addr.msf.frame)>37) cd->t[i-1].sec++; /* rounding a bit :) */   if ((cd->t[i-1].sec=cd->t[i].sec-cd->t[i-1].sec)<0) {    cd->t[i-1].min--;cd->t[i-1].sec+=60; /* adjust minutes */   }  } } /* now the leadout for track[0] + track[last] */ cd->cdte[0].cdte_track=CDROM_LEADOUT; cd->cdte[0].cdte_format=CDROM_MSF; if (ioctl(cd->fd, CDROMREADTOCENTRY, &cd->cdte[0])<0)  return -1; else {  cd->t[0].audio=cd->cdte[0].cdte_ctrl & CDROM_DATA_TRACK;  cd->t[0].min=cd->cdte[0].cdte_addr.msf.minute;  cd->t[0].sec=cd->cdte[0].cdte_addr.msf.second;  cd->t[0].cddb =    cd->cdte[0].cdte_addr.msf.minute*60 +    cd->cdte[0].cdte_addr.msf.second; /* cddb[0] this last id */  cd->t[i-1].min=cd->t[0].min-cd->t[i-1].min;  cd->t[i-1].cddb = cd->cdte[i-1].cdte_addr.msf.minute*60*75 +    cd->cdte[i-1].cdte_addr.msf.second*75 +    cd->cdte[i-1].cdte_addr.msf.frame; /* cddb[last] */  if ((cd->cdte[i].cdte_addr.msf.frame)>37) cd->t[i-1].sec++; /* rounding a bit :) */  if ((cd->t[i-1].sec=cd->t[0].sec-cd->t[i-1].sec)<0) {   cd->t[i-1].min--;cd->t[i-1].sec+=60; /* adjust minutes */  } } updates[U_TRACKS]=1; cd->title[1]=cdth.cdth_trk1; /* init all these stuff */ if ((cddb=wmdb_getentries(&cd[0]))) return cddb; return cddb=cddb_getentries(&cd[0]); /* one of them */}int cd_readsubchannel(struct mcd *cd) { struct cdrom_volctrl cdv; /* Volume Stuff */ /* trackinfos */ cd->cds.cdsc_format = CDROM_MSF; /* reading MSF format */ if (ioctl(cd->fd,CDROMSUBCHNL,&cd->cds)<0) return -1; /* audiostatus changed */ if (cd->cds.cdsc_audiostatus!=cd->status) { /* also NO_[DISC|INFO] */  cd->status=cd->cds.cdsc_audiostatus;  /* intro */  if (cd->method==M_INTRO && cd->status==CDROM_AUDIO_COMPLETED) {   cd->title[0]++; updates[U_TRACKS]=1;   cd_start(&cd[0]);  }  /* repeat cd */  if (cd->method==M_REPEAT_CD &&  cd->title[0]==cd->title[1] &&  cd->status==CDROM_AUDIO_COMPLETED) {   cd->title[0]=1; updates[U_TRACKS]=1;   cd_start(&cd[0]);  }  /* needed for the last track */  if (cd->method==M_REPEAT_TRK && cd->status==CDROM_AUDIO_COMPLETED) {   cd_start(&cd[0]);  }  updates[U_STATUS]=1; /* show status */ } /* volume(0..3) changed */ if (ioctl(cd->fd,CDROMVOLREAD,&cdv)<0) return -1; if (cdv.channel0!=cd->vol.channel0) {  cd->vol.channel0=cdv.channel0; updates[U_VOLUME]=1; } if (cdv.channel1!=cd->vol.channel1) {  cd->vol.channel1=cdv.channel1; updates[U_VOLUME]=1; } if (cdv.channel2!=cd->vol.channel2) {  cd->vol.channel2=cdv.channel2; updates[U_VOLUME]=1; } if (cdv.channel3!=cd->vol.channel3) {  cd->vol.channel3=cdv.channel3; updates[U_VOLUME]=1; } /* track changed */ if (cd->cds.cdsc_trk!=cd->title[0] && cd->method!=M_INTRO) { /* title[0]=current title[1]=max */  if (cd->method==M_REPEAT_TRK) {   cd_start(&cd[0]);   return cd->title[0];  }  cd->title[0]=cd->cds.cdsc_trk;  updates[U_TRACKS]=1; } return cd->cds.cdsc_trk; /* current title may be usefull :) */}/* set title[0] to new track before */void cd_start(struct mcd *cd) { struct cdrom_msf msf; /* checking for last/first */ if (cd->title[0]>cd->title[1]) cd->title[0]=1; if (cd->title[0]<1) cd->title[0]=cd->title[1]; msf.cdmsf_min0   = cd->cdte[cd->title[0]].cdte_addr.msf.minute; msf.cdmsf_sec0   = cd->cdte[cd->title[0]].cdte_addr.msf.second; msf.cdmsf_frame0 = cd->cdte[cd->title[0]].cdte_addr.msf.frame; if (cd->method==M_INTRO) {  msf.cdmsf_min1   = cd->cdte[cd->title[0]].cdte_addr.msf.minute;  msf.cdmsf_sec1   = cd->cdte[cd->title[0]].cdte_addr.msf.second+MCD_INTRO_TIME;  if (msf.cdmsf_sec1>=60) { msf.cdmsf_min1++; msf.cdmsf_sec1-=60; }  msf.cdmsf_frame1 = cd->cdte[cd->title[0]].cdte_addr.msf.frame; } else {  /* leadout */  msf.cdmsf_sec1   = cd->cdte[0].cdte_addr.msf.second;  msf.cdmsf_min1   = cd->cdte[0].cdte_addr.msf.minute;  msf.cdmsf_frame1 = cd->cdte[0].cdte_addr.msf.frame; } cd_playmsf(&cd[0], &msf); return;}/* only for skipping, rest is done via cd_play(..)! */void cd_skip(struct mcd *cd, int secs) { struct cdrom_msf msf; if (cd->method==M_INTRO) return; /* skipping @intros ? */ if ((cd->title[0]==1) && (secs<0)) {  if (cd->cds.cdsc_absaddr.msf.minute*60+cd->cds.cdsc_absaddr.msf.second+secs<=2)  return; /* we ignore such things -- start */ } secs += cd->cds.cdsc_absaddr.msf.minute * 60 + cd->cds.cdsc_absaddr.msf.second; msf.cdmsf_min0   = secs / 60; msf.cdmsf_sec0   = secs % 60; msf.cdmsf_frame0 = 0; msf.cdmsf_min1   = cd->cdte[0].cdte_addr.msf.minute; msf.cdmsf_sec1   = cd->cdte[0].cdte_addr.msf.second; msf.cdmsf_frame1 = cd->cdte[0].cdte_addr.msf.frame; if (msf.cdmsf_min0*60*75+msf.cdmsf_sec0*75+msf.cdmsf_frame0  >  msf.cdmsf_min1*60*75+msf.cdmsf_sec1*75+msf.cdmsf_frame1)  return; /* we ignore also this -- end */ cd_playmsf(&cd[0], &msf); return;}void cd_stop(struct mcd *cd) { if (cd->cds.cdsc_audiostatus == CDROM_AUDIO_PLAY) if (ioctl(cd->fd,CDROMSTOP,NULL)<0)  draw_status("error stopping",1); return;}void cd_pauseresume(struct mcd *cd) { switch (cd->cds.cdsc_audiostatus) { case CDROM_AUDIO_PLAY:  ioctl(cd->fd,CDROMPAUSE,NULL); break; case CDROM_AUDIO_PAUSED:  ioctl(cd->fd,CDROMRESUME,NULL); break; default: draw_status("request ignored",1); } return;}void cd_eject(int *fd) { draw_status("opening cdrom",1); ioctl(*fd,CDROMSTOP,NULL); ioctl(*fd,CDROMEJECT,NULL); return;}void cd_close(int *fd) { draw_status("reading cdrom",1); ioctl(*fd,CDROMCLOSETRAY,NULL); updates[U_ALL]=1; return;}

⌨️ 快捷键说明

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