--- cdinfo.c.orig Sun May 7 23:37:32 2000 +++ cdinfo.c Wed May 10 21:01:30 2000 @@ -408,6 +408,203 @@ return c; } +#elif defined(sun) +#include + +/* + * トラック情報の取得 + */ +static struct cdrom_msf lba2msf (u_int from, u_int to); + +static struct cdrom_msf +lba2msf (u_int from, u_int to) +{ + struct cdrom_msf msf; + + msf.cdmsf_min0 = (from + 150) / (60 * 75); + msf.cdmsf_sec0 = (from + 150) / 75 - msf.cdmsf_min0 * 60; + msf.cdmsf_frame0 = (from + 150) - msf.cdmsf_sec0 * 75 - msf.cdmsf_min0 * 60 * 75; + + msf.cdmsf_min1 = (to + 150) / (60 * 75); + msf.cdmsf_sec1 = (to + 150) / 75 - msf.cdmsf_min1 * 60; + msf.cdmsf_frame1 = (to + 150) - msf.cdmsf_sec1 * 75 - msf.cdmsf_min1 * 60 * 75; + + return msf; +} + +static int +cdinfo_get_entry(CDInfo *info) +{ + struct cdrom_tochdr toc_header; + struct cdrom_tocentry toc; + int no, endtrk, i; + struct cdrom_msf tocmsf[100]; + + /* 情報クリア */ + if (info->infos) + free(info->infos); + info->track_no = 0; + + if (ioctl(info->fd, CDROMREADTOCHDR, &toc_header) < 0) { + return -1; + } + + /* ヘッダ情報取得 */ + no = endtrk = toc_header.cdth_trk1; + + /* TOC 情報取得 */ + toc.cdte_format = CDROM_MSF; + for (i = 1; i <=endtrk; i++) { + toc.cdte_track = i; + if (ioctl(info->fd, CDROMREADTOCENTRY, &toc) < 0) { + return -1; + } + tocmsf[i - 1].cdmsf_min0 = toc.cdte_addr.msf.minute; + tocmsf[i - 1].cdmsf_sec0 = toc.cdte_addr.msf.second; + tocmsf[i - 1].cdmsf_frame0 = toc.cdte_addr.msf.frame; + } + toc.cdte_track = CDROM_LEADOUT; + if (ioctl(info->fd, CDROMREADTOCENTRY, &toc) < 0) { + return -1; + } + + if (ioctl(info->fd, CDROMREADTOCENTRY, (char *)&toc) < 0) { + return -1; + } + + info->track_no = no; + if ((info->infos = malloc(sizeof info->infos[0] * no)) == NULL) { + perror("cdinfo_get_entry"); + exit(1); + } + + { + /* 情報取得 */ + int i; + for (i=0; iinfos[i].block = msf2lba(tocmsf[i].cdmsf_min0, + tocmsf[i].cdmsf_sec0, + tocmsf[i].cdmsf_frame0); + info->infos[i].len = msf2lba(tocmsf[i+1].cdmsf_min0, + tocmsf[i+1].cdmsf_sec0, + tocmsf[i+1].cdmsf_frame0) - + info->infos[i].block; + fprintf(stderr, "block:%d len:%d\n", + info->infos[i].block, + info->infos[i].len); + + } + } + + return 0; +} + +int +cdinfo_play(CDInfo *info, int track_no) +{ + int start, len; + struct cdrom_msf msf; + + if (info) { + if (track_no > info->track_no) + return -1; + start = info->infos[track_no-1].block; + len = info->infos[track_no-1].len; + msf = lba2msf(start, start + len); + return ioctl(info->fd, CDROMPLAYMSF, &msf); + } else + return 0; +} + +int +cdinfo_stop(CDInfo *info) +{ + if (info) { + return ioctl(info->fd, CDROMSTOP); + } else + return 0; +} + +int +cdinfo_pause(CDInfo *info) +{ + if (info) { + return ioctl(info->fd, CDROMPAUSE); + } else + return 0; +} + +/* + * 現在の演奏中の時刻を取得 + */ +int +cdinfo_get_current_time(CDInfo *info, CDTimeInfo *current) +{ + if (info) { + + struct cdrom_subchnl s; + + s.cdsc_format = CDROM_MSF; + if (ioctl(info->fd, CDROMSUBCHNL, &s) < 0) { + return -1; + } + if (s.cdsc_audiostatus != CDROM_AUDIO_PLAY) { + return -1; + } + + if (current) + current->block = msf2lba(s.cdsc_reladdr.msf.minute, + s.cdsc_reladdr.msf.second, + s.cdsc_reladdr.msf.frame); + return 0; + + } else + return -1; +} + +int +cdinfo_set_volume(CDInfo *info, int vol) +{ + if (info) { + struct cdrom_volctrl v; + v.channel0 = vol; + v.channel1 = vol; + /* + v.channel2 = vol; + v.channel3 = vol; + */ + return ioctl(info->fd, CDROMVOLCTRL, &v); + } else + return 0; +} + +CDInfo * +cdinfo_new(const char *devicename) +{ + CDInfo *c; + int fd; + + if ((fd = open(devicename, O_RDONLY, 0)) < 0) { + return NULL; + } + + if ((c = malloc(sizeof *c)) == NULL) { + perror("cdinfo_new"); + exit(1); + } + + c->fd = fd; + c->track_no = 0; + c->infos = NULL; + + if (cdinfo_get_entry(c)) { + cdinfo_delete(c); + return NULL; + } + + return c; +} + #else int cdinfo_play(CDInfo *cdinfo, int no) {return -1;}