📄 cddev.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 + -