123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- /* $OpenBSD: cdrom_freebsd.c,v 1.3 2010/05/17 08:31:11 espie Exp $ */
- /*
- * Copyright (C) 1990 Regents of the University of California.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of the University of
- * California not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. the University of California makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- */
- static int c;
- # include <stdio.h>
- # include <stdlib.h>
- # include <sys/file.h>
- # include <sys/types.h>
- # include <sys/param.h>
- # include <sys/stat.h>
- # include <string.h>
- # include <sys/buf.h>
- # include <sys/time.h>
- #include <sys/ioctl.h>
- #include <sys/disklabel.h>
- #include <sys/cdio.h>
- # include "debug.h"
- # include "cdrom_freebsd.h"
- # include "app.h"
- extern char *device;
- static char cdrom[] = "/dev/rcd0c";
- static char cdrom1[] = "/dev/rmcd0c";
- cdrom_info cdi;
- char info_filename[256];
- FILE *disc_info = NULL;
- static int cdrom_fd = -1;
- extern AppData app_data;
- get_stored_info()
- {
- int i,n;
- char line[100];
- char *title;
- if(disc_info) {
- fclose(disc_info);
- disc_info = NULL;
- }
- if ( cdi.maxtrack == 0) {
- return(0);
- }
- for (i = 0, n = 0; i < cdi.maxtrack; i++)
- n = n + ((i+1) * cdi.times[i]);
- n = n / cdi.maxtrack;
- disc_title = NULL;
- if (app_data.cdInfoDir != NULL)
- sprintf(info_filename, "%s/cd.%d", app_data.cdInfoDir, n);
- else
- sprintf(info_filename, "cd.%d", n);
- if ((disc_info = fopen(info_filename, "r")) != NULL)
- {
- fgets(line, 100, disc_info);
- title = strchr(line, ':');
- if (title != NULL)
- {
- *(strchr(title, '\n')) = '\0';
- disc_title = strdup(title + 1);
- }
- fgets(line, 100, disc_info);
- sscanf(line, "Program: %s", program_str);
- }
- else {
- disc_title = strdup(NOTITLESTR);
- program_str[0] = 0;
- }
- if (disc_title == NULL) {
- disc_title = strdup(NOTITLESTR);
- }
- }
- int
- cdrom_open() {
- int n;
- extern void update_title();
- if (cdrom_fd != -1)
- return(cdi.curtrack);
- if (app_data.device != NULL) {
- if ((cdrom_fd = open(app_data.device, O_RDONLY)) == -1) {
- perror(app_data.device);
- return(-1);
- }
- } else {
- if ( (cdrom_fd = open(cdrom, O_RDONLY)) == -1
- && (cdrom_fd = open(cdrom1, O_RDONLY)) == -1
- ) {
- perror("open: ");
- return(-1);
- }
- }
- if (cdrom_get_times() == -1) {
- cdrom_close();
- return(-1);
- }
- if ((n = cdrom_get_curtrack()) == -1)
- return(-1);
- get_stored_info();
- update_title();
- if (cdi.state & CDROM_STATE_PLAY)
- cdi.curtrack = n;
- if (cdi.state & CDROM_STATE_SHUFFLE)
- shuffle_setup();
- return(cdi.curtrack);
- }
- void
- cdrom_close() {
- if (cdrom_fd == -1)
- return;
- if (cdi.times != NULL) {
- free((char *) cdi.times);
- free((char *) cdi.addrs);
- cdi.times = NULL;
- cdi.addrs = NULL;
- }
- (void) close(cdrom_fd);
- cdrom_fd = -1;
- }
- int
- cdrom_start() {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOCSTART) == -1) {
- perror("ioctl(cdromstart)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_stop() {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOCSTOP) == -1) {
- perror("ioctl(cdromstop)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_eject() {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOCALLOW) == -1) {
- perror("ioctl(cdromallow)");
- return(-1);
- }
- if (ioctl(cdrom_fd, CDIOCEJECT) == -1) {
- perror("ioctl(cdromeject)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_pause() {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOCPAUSE) == -1) {
- perror("ioctl(cdrompause)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_resume() {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOCRESUME) == -1) {
- perror("ioctl(cdromresume)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_volume(left_vol, right_vol)
- int left_vol;
- int right_vol;
- {
- struct ioc_vol vol;
- if (cdrom_fd == -1)
- return(-1);
- vol.vol[0] = left_vol;
- vol.vol[1] = right_vol;
- vol.vol[2] = 0;
- vol.vol[3] = 0;
- if (ioctl(cdrom_fd, CDIOCSETVOL, &vol) == -1) {
- perror("ioctl(cdromvolctrl)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_get_times() {
- struct ioc_toc_header tochdr;
- extern unsigned short *ushort_malloc();
- extern struct msf *msf_malloc();
- unsigned long trk, trk_total, otime;
- struct msf msf;
- if (cdrom_read_tochdr(&tochdr) == -1)
- return(-1);
- cdi.mintrack = tochdr.starting_track;
- cdi.maxtrack = tochdr.ending_track;
- if (cdi.times != NULL)
- {
- free((char *) cdi.times);
- free((char *) cdi.addrs);
- cdi.times = NULL;
- cdi.addrs = NULL;
- }
- cdi.times = ushort_malloc(cdi.maxtrack - cdi.mintrack + 1);
- cdi.addrs = msf_malloc(cdi.maxtrack - cdi.mintrack + 2);
- otime = 0;
- for (trk = cdi.mintrack; trk <= cdi.maxtrack; trk++) {
- if (cdrom_get_msf(trk, &msf, &trk_total) == -1)
- return(-1);
- /* record start address for each track (track 1 starts at 0)*/
- cdi.addrs[trk - cdi.mintrack] = msf;
- trk_total -= otime;
- /* use start time of next track as length of previous */
- if (otime != 0)
- {
- cdi.times[trk - cdi.mintrack - 1] = trk_total;
- }
- otime += trk_total;
- }
- /* find start of leadout to get length of last track */
- if (cdrom_get_msf(CDROM_LEADOUT, &msf, &trk_total) == -1)
- return(-1);
- /* recode leadout start address */
- cdi.addrs[trk - cdi.mintrack] = msf;
- trk_total -= otime;
- otime += trk_total;
- cdi.times[trk - cdi.mintrack - 1] = trk_total;
- return(0);
- }
- int
- cdrom_get_curtrack() {
- struct cd_sub_channel_info data;
- if (cdrom_read_subchannel(&data) == -1)
- return(-1);
- switch (data.header.audio_status) {
- case CD_AS_AUDIO_INVALID:
- return(-1);
- /* playing track subchnl.cdsc_trk */
- case CD_AS_PLAY_IN_PROGRESS:
- return((int) data.what.position.track_number);
- /* paused on track subchnl.cdsc_trk */
- case CD_AS_PLAY_PAUSED:
- return((int) data.what.position.track_number);
- /* punt */
- case CD_AS_PLAY_COMPLETED:
- return(0);
- case CD_AS_PLAY_ERROR:
- return(-1);
- /* punt */
- case CD_AS_NO_STATUS:
- debug_printf(1, "cdrom_get_curtrack: no status\n");
- return(0);
- }
- /* bad value in cdsc_audiostatus */
- return(-1);
- }
- int
- cdrom_get_msf(track, msf, length)
- unsigned long track;
- struct msf *msf;
- unsigned long *length;
- {
- struct cd_toc_entry data;
-
- if (cdrom_read_tocentry(track, &data, sizeof(data)) == -1)
- return(-1);
- msf->minute = data.addr.msf.minute;
- msf->second = data.addr.msf.second;
- msf->frame = data.addr.msf.frame;
- *length = (((unsigned int) msf->minute) * 60) + (unsigned int) msf->second;
- return(0);
- }
- int
- cdrom_get_curmsf(msf)
- struct msf *msf;
- {
- struct cd_sub_channel_info data;
- if (cdrom_read_subchannel(&data) == -1)
- return(-1);
- msf->minute = data.what.position.absaddr.msf.minute;
- msf->second = data.what.position.absaddr.msf.second;
- msf->frame = data.what.position.absaddr.msf.frame;
- return (0);
- }
- int
- cdrom_play_track(start_track, end_track)
- unsigned char start_track;
- unsigned char end_track;
- {
- struct ioc_play_track ti;
- struct ioc_play_msf play_addr;
- char *addr;
- if (cdrom_fd == -1)
- return(-1);
- play_addr.start_m = cdi.addrs[start_track - cdi.mintrack].minute;
- play_addr.start_s = cdi.addrs[start_track - cdi.mintrack].second;
- play_addr.start_f = cdi.addrs[start_track - cdi.mintrack].frame;
- play_addr.end_m = cdi.addrs[end_track - cdi.mintrack + 1].minute;
- play_addr.end_s = cdi.addrs[end_track - cdi.mintrack + 1].second;
- play_addr.end_f = cdi.addrs[end_track - cdi.mintrack + 1].frame - 1;
- if(play_addr.end_f >= 75) {
- play_addr.end_f = 74;
- play_addr.end_s--;
- }
- if(play_addr.end_s >= 60) {
- play_addr.end_s = 59;
- play_addr.end_m--;
- }
- addr = (char *)&play_addr;
- if (ioctl(cdrom_fd, CDIOCPLAYMSF, &play_addr) == -1) {
- perror("ioctl(cdromplaymsftrk)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_play_msf(start_msf, end_msf)
- struct msf *start_msf;
- struct msf *end_msf;
- {
- struct ioc_play_msf play_addr;
- if (cdrom_fd == -1)
- return(-1);
- play_addr.start_m = start_msf->minute;
- play_addr.start_s = start_msf->second;
- play_addr.start_f = start_msf->frame;
- play_addr.end_m = end_msf->minute;
- play_addr.end_s = end_msf->second;
- play_addr.end_f = end_msf->frame;
- if (ioctl(cdrom_fd, CDIOCPLAYMSF, &play_addr) == -1) {
- perror("ioctl(cdromplaymsf)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_read_subchannel(data)
- struct cd_sub_channel_info *data;
- {
- struct ioc_read_subchannel subchnl;
- if (cdrom_fd == -1)
- return(-1);
- subchnl.address_format = CD_MSF_FORMAT;
- subchnl.data_format = CD_CURRENT_POSITION;
- subchnl.data_len = /* sizeof(struct cd_sub_channel_info)*/ 16;
- subchnl.track = 0;
- subchnl.data = data;
- if (ioctl(cdrom_fd, CDIOCREADSUBCHANNEL, (char *) &subchnl) == -1) {
- fprintf(stderr, "ioctl(cdromsubchnl): ");
- perror(cdrom);
- return(-1);
- }
- return(0);
- }
- int
- cdrom_read_track(track, data)
- unsigned int track;
- struct cd_sub_channel_info *data;
- {
- struct ioc_read_subchannel subchnl;
- if (cdrom_fd == -1)
- return(-1);
- subchnl.address_format = CD_MSF_FORMAT;
- subchnl.data_format = CD_TRACK_INFO;
- subchnl.data_len = /* sizeof(struct cd_sub_channel_info)*/ 24;
- subchnl.track = track;
- subchnl.data = data;
- if (ioctl(cdrom_fd, CDIOCREADSUBCHANNEL, (char *) &subchnl) == -1) {
- fprintf(stderr, "ioctl(cdromsubchnltrk): ");
- perror(cdrom);
- return(-1);
- }
- return(0);
- }
- int
- cdrom_read_tocentry(track, data, size)
- unsigned int track;
- struct cd_toc_entry *data;
- int size;
- {
- struct ioc_read_toc_entry tocentry;
- if (cdrom_fd == -1)
- return(-1);
- tocentry.starting_track = (unsigned char)track;
- tocentry.address_format = CD_MSF_FORMAT;
- tocentry.data_len = /* sizeof(struct cd_toc_entry)*/ size;
- tocentry.data = data;
- if (ioctl(cdrom_fd, CDIOREADTOCENTRYS, (char *) &tocentry) == -1) {
- perror("ioctl(cdromreadtocentry)");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_read_tochdr(tochdr)
- struct ioc_toc_header *tochdr;
- {
- if (cdrom_fd == -1)
- return(-1);
- if (ioctl(cdrom_fd, CDIOREADTOCHEADER, (char *) tochdr) == -1) {
- perror("ioctl(cdromreadtochdr): ");
- return(-1);
- }
- return(0);
- }
- int
- cdrom_status() {
- struct cd_sub_channel_info data;
- if (cdrom_read_subchannel(&data) == -1)
- return(-1);
- switch (data.header.audio_status) {
- case CD_AS_AUDIO_INVALID:
- return(CDROM_INVALID);
- case CD_AS_PLAY_IN_PROGRESS:
- return(CDROM_PLAYING);
- case CD_AS_PLAY_PAUSED:
- return(CDROM_PAUSED);
- case CD_AS_PLAY_COMPLETED:
- return(CDROM_COMPLETED);
- case CD_AS_PLAY_ERROR:
- return(CDROM_ERROR);
- case CD_AS_NO_STATUS:
- return(CDROM_NO_STATUS);
- }
- return(-1);
- }
- unsigned short *
- ushort_malloc(n)
- int n;
- {
- unsigned short *ptr;
- ptr = (unsigned short *) calloc(n, sizeof(unsigned short));
- if (ptr == NULL) {
- perror("calloc");
- exit(1);
- }
- return(ptr);
- }
- struct msf *
- msf_malloc(n)
- int n;
- {
- struct msf *ptr;
- ptr = (struct msf *) calloc(n, sizeof(struct msf));
- if (ptr == NULL) {
- perror("calloc");
- exit(1);
- }
- return(ptr);
- }
- int
- cdrom_disp_cdi() {
- int trk;
- fprintf(stderr,"CDI structure:\n");
- fprintf(stderr,"\tcurtrack: %d\n",cdi.curtrack);
- fprintf(stderr,"\tmin: %d max: %d total: %d\n",
- cdi.mintrack, cdi.maxtrack, cdi.ntracks);
- fprintf(stderr,"\tdur: %d state: %2x\n",cdi.duration, cdi.state);
- fprintf(stderr,"\tcurrand: %d lastprog: %d\n",
- cdi.currand, cdi.lastprog);
- fprintf(stderr,"\n\tTracklist:\n");
- if (cdi.maxtrack != cdi.mintrack) {
- for (trk=0; trk<=cdi.maxtrack-cdi.mintrack+1; trk++) {
- fprintf(stderr,"\t%3d: %d %02d:%02d %d\n",trk,cdi.times[trk],
- cdi.addrs[trk].minute,cdi.addrs[trk].second,
- cdi.addrs[trk].frame);
- }
- }
- }
|