From 0327f33923e0861e59dbaba696f86d87149eb885 Mon Sep 17 00:00:00 2001 From: Charles Schmidt Date: Sun, 28 Jul 2002 22:45:45 +0000 Subject: Added *BSD (and Darwin) ioctl cdaudio playing. Couple bugfixes. 'end-track','current-track' and 'cddb-discid' propert... Original commit message from CVS: Added *BSD (and Darwin) ioctl cdaudio playing. Couple bugfixes. 'end-track','current-track' and 'cddb-discid' properties and 'track-change' signal for the element. --- sys/cdrom/Makefile.am | 2 +- sys/cdrom/gstcdplayer.c | 85 +++++++-- sys/cdrom/gstcdplayer.h | 6 +- sys/cdrom/gstcdplayer_ioctl.c | 168 +++++++---------- sys/cdrom/gstcdplayer_ioctl.h | 18 +- sys/cdrom/gstcdplayer_ioctl_bsd.h | 338 ++++++++++++++++++++++++++++++++++ sys/cdrom/gstcdplayer_ioctl_irix.h | 109 +++++++++++ sys/cdrom/gstcdplayer_ioctl_solaris.h | 204 ++++++++++++++++++++ 8 files changed, 807 insertions(+), 123 deletions(-) create mode 100644 sys/cdrom/gstcdplayer_ioctl_bsd.h create mode 100644 sys/cdrom/gstcdplayer_ioctl_irix.h create mode 100644 sys/cdrom/gstcdplayer_ioctl_solaris.h (limited to 'sys/cdrom') diff --git a/sys/cdrom/Makefile.am b/sys/cdrom/Makefile.am index a43c1dcb..c3d0600d 100644 --- a/sys/cdrom/Makefile.am +++ b/sys/cdrom/Makefile.am @@ -7,4 +7,4 @@ libgstcdplayer_la_CFLAGS = $(GST_CFLAGS) libgstcdplayer_la_LIBADD = libgstcdplayer_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = gstcdplayer.h gstcdplayer_ioctl.h +noinst_HEADERS = gstcdplayer.h gstcdplayer_ioctl.h gstcdplayer_ioctl_solaris.h gstcdplayer_ioctl_bsd.h diff --git a/sys/cdrom/gstcdplayer.c b/sys/cdrom/gstcdplayer.c index 2bbbddb2..7852276f 100644 --- a/sys/cdrom/gstcdplayer.c +++ b/sys/cdrom/gstcdplayer.c @@ -17,8 +17,9 @@ * Boston, MA 02111-1307, USA. */ +/* #define GST_DEBUG_ENABLED */ + #include "gstcdplayer.h" -#include "gstcdplayer_ioctl.h" /* props */ enum { @@ -26,10 +27,14 @@ enum { ARG_DEVICE, ARG_NUM_TRACKS, ARG_START_TRACK, + ARG_END_TRACK, + ARG_CURRENT_TRACK, + ARG_CDDB_DISCID, }; /* signals */ enum { + TRACK_CHANGE, LAST_SIGNAL, }; @@ -38,6 +43,7 @@ static void cdplayer_init(CDPlayer *cdp); static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *spec); static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *spec); static void cdplayer_dispose(GObject *object); +static gboolean cdplayer_iterate(GstBin *bin); static GstElementStateReturn cdplayer_change_state(GstElement *element); static gboolean plugin_init(GModule *module,GstPlugin *plugin); @@ -45,7 +51,7 @@ static gboolean plugin_init(GModule *module,GstPlugin *plugin); static GstElementClass *parent_class; -/* static guint cdplayer_signals[LAST_SIGNAL] = {0}; */ + static guint cdplayer_signals[LAST_SIGNAL] = {0}; static GstElementDetails cdplayer_details = { @@ -87,19 +93,27 @@ static void cdplayer_class_init(CDPlayerClass *klass) { GObjectClass *gobject_klass; GstElementClass *gstelement_klass; + GstBinClass *gstbin_klass; gobject_klass = (GObjectClass *)klass; gstelement_klass = (GstElementClass *)klass; + gstbin_klass = (GstBinClass *)klass; parent_class = g_type_class_ref(gst_bin_get_type()); gobject_klass->dispose = GST_DEBUG_FUNCPTR(cdplayer_dispose); gstelement_klass->change_state = GST_DEBUG_FUNCPTR(cdplayer_change_state); + gstbin_klass->iterate = GST_DEBUG_FUNCPTR(cdplayer_iterate); g_object_class_install_property(gobject_klass,ARG_DEVICE,g_param_spec_string("device","device","CDROM device",NULL,G_PARAM_READWRITE)); g_object_class_install_property(gobject_klass,ARG_NUM_TRACKS,g_param_spec_int("num_tracks","num_tracks","Number of Tracks",G_MININT,G_MAXINT,0,G_PARAM_READABLE)); - g_object_class_install_property(gobject_klass,ARG_START_TRACK,g_param_spec_int("start_track","start_track","Track to start playback on",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READABLE)); + g_object_class_install_property(gobject_klass,ARG_START_TRACK,g_param_spec_int("start_track","start_track","Track to start playback on",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READWRITE)); + g_object_class_install_property(gobject_klass,ARG_END_TRACK,g_param_spec_int("end_track","end_track","Track to end playback on",0,CDPLAYER_MAX_TRACKS-1,0,G_PARAM_READWRITE)); + g_object_class_install_property(gobject_klass,ARG_CURRENT_TRACK,g_param_spec_int("current_track","current_track","Current track playing",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READABLE)); + g_object_class_install_property(gobject_klass,ARG_CDDB_DISCID,g_param_spec_uint("cddb_discid","cddb_discid","CDDB Disc ID",0,G_MAXUINT,1,G_PARAM_READABLE)); + + cdplayer_signals[TRACK_CHANGE] = g_signal_new("track_change",G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,G_STRUCT_OFFSET(CDPlayerClass,track_change),NULL,NULL,gst_marshal_VOID__INT,G_TYPE_NONE,1,G_TYPE_INT); gobject_klass->set_property = cdplayer_set_property; gobject_klass->get_property = cdplayer_get_property; @@ -112,11 +126,12 @@ static void cdplayer_init(CDPlayer *cdp) cdp->device = g_strdup("/dev/cdrom"); cdp->num_tracks = -1; cdp->start_track = 1; + cdp->end_track = 0; + cdp->current_track = 1; cdp->paused = FALSE; - GST_FLAG_SET(cdp,GST_BIN_FLAG_MANAGER); - GST_FLAG_SET(cdp,GST_BIN_SELF_SCHEDULABLE); +// GST_FLAG_SET(cdp,GST_BIN_FLAG_MANAGER); return; } @@ -140,7 +155,12 @@ static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *va break; case ARG_START_TRACK: // FIXME prolly should uhh.. restart play, i guess... or something whatever - cdp->start_track = g_value_get_int(value); +// FIXME we should only set current_track if its not playing... + cdp->current_track = cdp->start_track = g_value_get_int(value); + break; + case ARG_END_TRACK: +// FIXME prolly should restart play, maybe, or try to set it without interrupt.. + cdp->end_track = g_value_get_int(value); break; default: break; @@ -168,6 +188,13 @@ static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GP case ARG_START_TRACK: g_value_set_int(value,cdp->start_track); break; + case ARG_END_TRACK: + g_value_set_int(value,cdp->end_track); + case ARG_CURRENT_TRACK: + g_value_set_int(value,cdp->current_track); + break; + case ARG_CDDB_DISCID: + g_value_set_uint(value,cdp->cddb_discid); default: break; } @@ -182,20 +209,49 @@ static void cdplayer_dispose(GObject *object) g_return_if_fail(GST_IS_CDPLAYER(object)); cdp = CDPLAYER(object); - - G_OBJECT_CLASS(parent_class)->dispose(object); - g_free(cdp->device); - if (GST_ELEMENT_SCHED(cdp)) { - gst_scheduler_reset(GST_ELEMENT_SCHED(cdp)); - gst_object_unref(GST_OBJECT(GST_ELEMENT_SCHED(cdp))); - GST_ELEMENT_SCHED(cdp) = NULL; + if (G_OBJECT_CLASS(parent_class)->dispose) { + G_OBJECT_CLASS(parent_class)->dispose(object); } return; } +static gboolean cdplayer_iterate(GstBin *bin) +{ + CDPlayer *cdp = CDPLAYER(bin); + gint current_track; + + switch (cd_status(CDPLAYER_CD(cdp))) { + case CD_PLAYING: + current_track = cd_current_track(CDPLAYER_CD(cdp)); + if (current_track > cdp->end_track && cdp->end_track != 0) { + return FALSE; + } + + if (current_track != -1 && current_track != cdp->current_track) { + cdp->current_track = current_track; + g_signal_emit(G_OBJECT(cdp),cdplayer_signals[TRACK_CHANGE],0,cdp->current_track); + } + + return TRUE; + break; + case CD_ERROR: + gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PAUSED); + return FALSE; + break; + case CD_COMPLETED: + gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PAUSED); + gst_element_set_eos(GST_ELEMENT(bin)); + return FALSE; + break; + } + + return FALSE; +} + + static GstElementStateReturn cdplayer_change_state(GstElement *element) { CDPlayer *cdp; @@ -213,6 +269,7 @@ static GstElementStateReturn cdplayer_change_state(GstElement *element) return GST_STATE_FAILURE; } cdp->num_tracks = cdp->cd.num_tracks; + cdp->cddb_discid = cd_cddb_discid(CDPLAYER_CD(cdp)); } break; case GST_STATE_PAUSED: @@ -234,7 +291,7 @@ static GstElementStateReturn cdplayer_change_state(GstElement *element) cdp->paused = FALSE; } else { - if (cd_start(CDPLAYER_CD(cdp),cdp->start_track) == FALSE) { + if (cd_start(CDPLAYER_CD(cdp),cdp->start_track,cdp->end_track) == FALSE) { return GST_STATE_FAILURE; } } diff --git a/sys/cdrom/gstcdplayer.h b/sys/cdrom/gstcdplayer.h index 5da5527d..39aaaf43 100644 --- a/sys/cdrom/gstcdplayer.h +++ b/sys/cdrom/gstcdplayer.h @@ -45,7 +45,10 @@ struct _CDPlayer { /* properties */ gchar *device; gint num_tracks; - guint start_track; + gint start_track; + gint end_track; + gint current_track; + guint32 cddb_discid; /* private */ struct cd cd; @@ -56,6 +59,7 @@ struct _CDPlayerClass { GstBinClass parent_class; /* signal callbacks */ + void (*track_change) (GstElement *element,guint track); }; GType cdplayer_get_type(void); diff --git a/sys/cdrom/gstcdplayer_ioctl.c b/sys/cdrom/gstcdplayer_ioctl.c index 2da746a2..532d9fc1 100644 --- a/sys/cdrom/gstcdplayer_ioctl.c +++ b/sys/cdrom/gstcdplayer_ioctl.c @@ -29,137 +29,97 @@ #include #include -#include - - -gboolean cd_init(struct cd *cd,const gchar *device) -{ - struct cdrom_tochdr toc_header; - struct cdrom_tocentry toc_entry; - guint i; - - cd->fd = open(device,O_RDONLY | O_NONBLOCK); - - if (cd->fd == -1) { - return FALSE; - } - - /* get the toc header information */ - if (ioctl(cd->fd,CDROMREADTOCHDR,&toc_header) != 0) { - return FALSE; - } - - /* read each entry in the toc header */ - for (i = 1; i < toc_header.cdth_trk1; i++) { - toc_entry.cdte_format = CDROM_MSF; - toc_entry.cdte_track = i; - if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { - return FALSE; - } +/* private functions */ +static void cd_fix_track_range(struct cd *cd,gint *start_track,gint *end_track); +static gint cddb_sum(gint n); - cd->tracks[i].minute = toc_entry.cdte_addr.msf.minute; - cd->tracks[i].second = toc_entry.cdte_addr.msf.second; - cd->tracks[i].frame = toc_entry.cdte_addr.msf.frame; - cd->tracks[i].data_track = (toc_entry.cdte_ctrl == CDROM_DATA_TRACK); - } - - /* read the leadout */ - toc_entry.cdte_track = CDROM_LEADOUT; - toc_entry.cdte_format = CDROM_MSF; - if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { - return FALSE; - } - cd->tracks[LEADOUT].minute = toc_entry.cdte_addr.msf.minute; - cd->tracks[LEADOUT].second = toc_entry.cdte_addr.msf.second; - cd->tracks[LEADOUT].frame = toc_entry.cdte_addr.msf.frame; - cd->num_tracks = toc_header.cdth_trk1; - return TRUE; -} - -gboolean cd_start(struct cd *cd,guint start_track) +#ifdef HAVE_LINUX_CDROM_H +#include +#elif define HAVE_SYS_CDIO_H +#include +/* +irix cdaudio works quite a bit differently than ioctl(), so its not ready +#elif define HAVE_DMEDIA_CDAUDIO_H +#include +*/ +#endif + +/* these headers define low level functions: + gboolean cd_init(struct cd *cd,const gchar *device); + gboolean cd_start(struct cd *cd,gint start_track,gint end_track); + gboolean cd_pause(struct cd *cd); + gboolean cd_resume(struct cd *cd); + gboolean cd_stop(struct cd *cd); + CDStatus cd_status(struct cd *cd); + gint cd_current_track(struct cd *cd); + gboolean cd_close(struct cd *cd); +*/ +#ifdef HAVE_CDROM_SOLARIS +#include "gstcdplayer_ioctl_solaris.h" +#elif defined HAVE_CDROM_BSD +#include "gstcdplayer_ioctl_bsd.h" +/* +#elif define HAVE_CDROM_IRIX +#include "gstcdplayer_ioctl_irix.h" +*/ +#endif + +static void cd_fix_track_range(struct cd *cd,gint *start_track,gint *end_track) { - struct cdrom_msf msf; - - if (cd->fd == -1) { - return FALSE; + if (*start_track <= 0) { + *start_track = 1; } - if (start_track <= 0) { - start_track = 1; + if (*start_track > cd->num_tracks) { + *start_track = cd->num_tracks; } - if (start_track > cd->num_tracks) { - start_track = cd->num_tracks; + if (*end_track < *start_track && *end_track != LEADOUT) { + *end_track = *start_track; } - msf.cdmsf_min0 = cd->tracks[start_track].minute; - msf.cdmsf_sec0 = cd->tracks[start_track].second; - msf.cdmsf_frame0 = cd->tracks[start_track].frame; - - msf.cdmsf_min1 = cd->tracks[LEADOUT].minute; - msf.cdmsf_sec1 = cd->tracks[LEADOUT].second; - msf.cdmsf_frame1 = cd->tracks[LEADOUT].frame; - - if (ioctl(cd->fd,CDROMPLAYMSF,&msf) != 0) { - return FALSE; + if (*end_track > cd->num_tracks || *end_track + 1 > cd->num_tracks) { + *end_track = LEADOUT; } - return TRUE; + return; } -gboolean cd_pause(struct cd *cd) -{ - if (cd->fd == -1) { - return FALSE; - } - if (ioctl(cd->fd,CDROMPAUSE,NULL) != 0) { - return FALSE; - } +/* this cddb info is from + http://www.freedb.org/modules.php?name=Sections&sop=viewarticle&artid=6 - return TRUE; -} - -gboolean cd_resume(struct cd *cd) + this will probably be of interest to anyone wishing to actually use the discid + http://www.freedb.org/modules.php?name=Sections&sop=viewarticle&artid=28 +*/ +static gint cddb_sum(gint n) { - if (cd->fd == -1) { - return FALSE; - } + gint ret = 0; - if (ioctl(cd->fd,CDROMRESUME,NULL) != 0) { - return FALSE; + while (n > 0) { + ret += n % 10; + n /= 10; } - return TRUE; + return ret; } -gboolean cd_stop(struct cd *cd) +guint32 cd_cddb_discid(struct cd *cd) { - if (cd->fd == -1) { - return FALSE; - } - - if (ioctl(cd->fd,CDROMSTOP,NULL) != 0) { - return FALSE; - } - - return TRUE; -} - + guint i; + guint n = 0; + guint t; -gboolean cd_close(struct cd *cd) -{ - if (cd->fd == -1) { - return TRUE; + for (i = 1; i <= cd->num_tracks; i++) { + n += cddb_sum(cd->tracks[i].minute * 60 + cd->tracks[i].second); } - if (close(cd->fd) != 0) { - return FALSE; - } + t = (cd->tracks[LEADOUT].minute * 60 + cd->tracks[LEADOUT].second) - (cd->tracks[1].minute * 60 + cd->tracks[1].second); - return TRUE; + return ((n % 0xff) << 24 | t << 8 | (cd->num_tracks)); } + diff --git a/sys/cdrom/gstcdplayer_ioctl.h b/sys/cdrom/gstcdplayer_ioctl.h index 7d96925c..e9fa1a63 100644 --- a/sys/cdrom/gstcdplayer_ioctl.h +++ b/sys/cdrom/gstcdplayer_ioctl.h @@ -17,8 +17,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __CDPLAYER_IOCTL_H__ -#define __CDPLAYER_IOCTL_H__ +#ifndef __CDPLAYER_LL_H__ +#define __CDPLAYER_LL_H__ #ifdef HAVE_CONFIG_H #include @@ -32,6 +32,12 @@ #define CDPLAYER_MAX_TRACKS 128 +typedef enum { + CD_PLAYING, + CD_COMPLETED, + CD_ERROR +} CDStatus; + struct cd_msf { guint8 minute; guint8 second; @@ -46,13 +52,19 @@ struct cd { struct cd_msf tracks[CDPLAYER_MAX_TRACKS]; }; + +/* these are defined by the different cdrom type header files */ gboolean cd_init(struct cd *cd,const gchar *device); -gboolean cd_start(struct cd *cd,guint start_track); +gboolean cd_start(struct cd *cd,gint start_track,gint end_track); gboolean cd_pause(struct cd *cd); gboolean cd_resume(struct cd *cd); gboolean cd_stop(struct cd *cd); +CDStatus cd_status(struct cd *cd); +gint cd_current_track(struct cd *cd); gboolean cd_close(struct cd *cd); +guint32 cd_cddb_discid(struct cd *cd); + #endif diff --git a/sys/cdrom/gstcdplayer_ioctl_bsd.h b/sys/cdrom/gstcdplayer_ioctl_bsd.h new file mode 100644 index 00000000..371c1300 --- /dev/null +++ b/sys/cdrom/gstcdplayer_ioctl_bsd.h @@ -0,0 +1,338 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CDROM_BSD_NETBSD /* net & open */ +gboolean cd_init(struct cd *cd,const gchar *device) +{ + struct ioc_toc_header toc_header; + struct ioc_read_toc_entry toc_entry; + struct cd_toc_entry toc_entry_data; + guint i; + + cd->fd = open(device,O_RDONLY | O_NONBLOCK); + + if (cd->fd == -1) { + return FALSE; + } + + /* get the toc header information */ + if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + /* read each entry in the toc header */ + for (i = 1; i <= toc_header.ending_track; i++) { + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = i; + toc_entry.data = &toc_entry_data; + toc_entry.data_len = sizeof(toc_entry_data); + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[i].minute = toc_entry.data->addr.msf.minute; + cd->tracks[i].second = toc_entry.data->addr.msf.second; + cd->tracks[i].frame = toc_entry.data->addr.msf.frame; + cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4; + } + + /* read the leadout */ + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = 0xAA; /* leadout */ + toc_entry.data = &toc_entry_data; + toc_entry.data_len = sizeof(toc_entry_data); + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[LEADOUT].minute = toc_entry.data->addr.msf.minute; + cd->tracks[LEADOUT].second = toc_entry.data->addr.msf.second; + cd->tracks[LEADOUT].frame = toc_entry.data->addr.msf.frame; + + cd->num_tracks = toc_header.ending_track; + + return TRUE; +} +#elif defined HAVE_CDROM_BSD_DARWIN +gboolean cd_init(struct cd *cd,const gchar *device) +{ + struct ioc_toc_header toc_header; + struct ioc_read_toc_entry toc_entry; + guint i; + + cd->fd = open(device,O_RDONLY | O_NONBLOCK); + + if (cd->fd == -1) { + return FALSE; + } + + /* get the toc header information */ + if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + /* read each entry in the toc header */ + for (i = 1; i <= toc_header.ending_track; i++) { + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = i; + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[i].minute = toc_entry.data->addr[1]; + cd->tracks[i].second = toc_entry.data->addr[2]; + cd->tracks[i].frame = toc_entry.data->addr[3]; + cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4; + } + + /* read the leadout */ + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = 0xAA; /* leadout */ + toc_entry.data = &toc_entry_data; + toc_entry.data_len = sizeof(toc_entry_data); + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[LEADOUT].minute = toc_entry.data->addr[1]; + cd->tracks[LEADOUT].second = toc_entry.data->addr[2]; + cd->tracks[LEADOUT].frame = toc_entry.data->addr[3]; + + cd->num_tracks = toc_header.ending_track; + + return TRUE; +} +#else /* free */ +gboolean cd_init(struct cd *cd,const gchar *device) +{ + struct ioc_toc_header toc_header; + struct ioc_read_toc_entry toc_entry; + guint i; + + cd->fd = open(device,O_RDONLY | O_NONBLOCK); + + if (cd->fd == -1) { + return FALSE; + } + + /* get the toc header information */ + if (ioctl(cd->fd,CDIOREADTOCHDR,&toc_header) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + /* read each entry in the toc header */ + for (i = 1; i <= toc_header.ending_track; i++) { + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = i; + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[i].minute = toc_entry.entry.addr.msf.minute; + cd->tracks[i].second = toc_entry.entry.addr.msf.second; + cd->tracks[i].frame = toc_entry.entry.addr.msf.frame; + cd->tracks[i].data_track = (toc_entry.data->control & 4) == 4; + } + + /* read the leadout */ + toc_entry.address_format = CD_MSF_FORMAT; + toc_entry.starting_track = 0xAA; /* leadout */ + toc_entry.data = &toc_entry_data; + toc_entry.data_len = sizeof(toc_entry_data); + + if (ioctl(cd->fd,CDIOREADTOCENTRYS,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[LEADOUT].minute = toc_entry.entry.addr.msf.minute; + cd->tracks[LEADOUT].second = toc_entry.entry.addr.msf.second; + cd->tracks[LEADOUT].frame = toc_entry.entry.addr.msf.frame; + + cd->num_tracks = toc_header.ending_track; + + return TRUE; +} +#endif + +gboolean cd_start(struct cd *cd,gint start_track,gint end_track) +{ + struct ioc_play_msf msf; + + if (cd->fd == -1) { + return FALSE; + } + + cd_fix_track_range(cd,&start_track,&end_track); + + msf.start_m = cd->tracks[start_track].minute; + msf.start_s = cd->tracks[start_track].second; + msf.start_f = cd->tracks[start_track].frame; + + if (end_track == LEADOUT) { + msf.end_m = cd->tracks[end_track].minute; + msf.end_s = cd->tracks[end_track].second; + msf.end_f = cd->tracks[end_track].frame; + } else { + msf.end_m = cd->tracks[end_track+1].minute; + msf.end_s = cd->tracks[end_track+1].second; + msf.end_f = cd->tracks[end_track+1].frame; + } + + if (ioctl(cd->fd,CDIOCPLAYMSF,&msf) != 0) { + return FALSE; + } + +} + +gboolean cd_pause(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDIOCPAUSE,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_resume(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDIOCRESUME,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_stop(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDIOCSTOP,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +/* -1 for error, 0 for not playing, 1 for playing */ +CDStatus cd_status(struct cd *cd) +{ + struct ioc_read_subchannel sub_channel; + struct cd_sub_channel_info sub_channel_info; + + if (cd->fd == -1) { + return -1; + } + + sub_channel.address_format = CD_MSF_FORMAT; + sub_channel.data_format = CD_CURRENT_POSITION; + sub_channel.track = 0; + sub_channel.data = &sub_channel_info; + sub_channel.data_len = sizeof(sub_channel_info); + + if (ioctl(cd->fd,CDIOCREADSUBCHANNEL,&sub_channel) != 0) { + return FALSE; + } + + switch (sub_channel.data->header.audio_status) { + case CD_AS_PLAY_IN_PROGRESS: + case CD_AS_PLAY_PAUSED: + return CD_PLAYING; + break; + case CD_AS_PLAY_COMPLETED: + return CD_COMPLETED; + break; + case CD_AS_AUDIO_INVALID: + case CD_AS_PLAY_ERROR: + default: + return CD_ERROR; + break; + + } +} + +gint cd_current_track(struct cd *cd) +{ + struct ioc_read_subchannel sub_channel; + struct cd_sub_channel_info sub_channel_info; + + if (cd->fd == -1) { + return -1; + } + + sub_channel.address_format = CD_MSF_FORMAT; + sub_channel.data_format = CD_TRACK_INFO; + sub_channel.track = 0; + sub_channel.data = &sub_channel_info; + sub_channel.data_len = sizeof(sub_channel_info); + + if (ioctl(cd->fd,CDIOCREADSUBCHANNEL,&sub_channel) != 0) { + return -1; + } + + return sub_channel.data->track_number; +} + +gboolean cd_close(struct cd *cd) +{ + if (cd->fd == -1) { + return TRUE; + } + + if (close(cd->fd) != 0) { + return FALSE; + } + + cd->fd = -1; + + return TRUE; +} + diff --git a/sys/cdrom/gstcdplayer_ioctl_irix.h b/sys/cdrom/gstcdplayer_ioctl_irix.h new file mode 100644 index 00000000..2f6be35c --- /dev/null +++ b/sys/cdrom/gstcdplayer_ioctl_irix.h @@ -0,0 +1,109 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* THIS DOES NOT WORK YET */ + +#define CDPLAYER(x) ((CDPlayer *)x) +#define FD(x) ((int)x) + +gboolean cd_init(struct cd *cd,const gchar *device) +{ + CDPLAYER *cdplayer; + CDSTATUS status; + CDTRACKINFO info; + guint i; + + cdplayer = CDOpen(device,"r"); + + if (cdplayer == NULL) { + return FALSE; + } + + cd->fd = FD(cdplayer); + + if (CDgetstatus(cdplayer,&status) == 0) { + CDclose(cdplayer); + cd->fd = 0; + return FALSE; + } + + for (i = 1; i < status.last; i++) { + if (CDgettrackinfo(cdplayer,i,&info) == 0) { + CDclose(cdplayer); + cd->fd = 0; + return FALSE; + } + + cd->tracks[i].minute = info.start_min; + cd->tracks[i].second = info.start_sec; + cd->tracks[i].frame = info.start_frame; + + } + + /* there is no leadout information */ + + + cd->num_tracks = status.last; + + return TRUE; +} + +gboolean cd_start(struct cd *cd,gint start_track,gint end_track) +{ + if (cd->fd == 0) { + return FALSE; + } + + cd_fix_track_range(cd,&start_track,&end_track); + + + +} + +gboolean cd_pause(struct cd *cd) +{ + +} + +gboolean cd_resume(struct cd *cd) +{ + +} + +gboolean cd_stop(struct cd *cd) +{ + +} + +/* -1 for error, 0 for not playing, 1 for playing */ +CDStatus cd_status(struct cd *cd) +{ + +} + +gint cd_current_track(struct cd *cd) +{ + +} + +gboolean cd_close(struct cd *cd) +{ + +} + diff --git a/sys/cdrom/gstcdplayer_ioctl_solaris.h b/sys/cdrom/gstcdplayer_ioctl_solaris.h new file mode 100644 index 00000000..868fb251 --- /dev/null +++ b/sys/cdrom/gstcdplayer_ioctl_solaris.h @@ -0,0 +1,204 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +gboolean cd_init(struct cd *cd,const gchar *device) +{ + struct cdrom_tochdr toc_header; + struct cdrom_tocentry toc_entry; + guint i; + + cd->fd = open(device,O_RDONLY | O_NONBLOCK); + + if (cd->fd == -1) { + return FALSE; + } + + /* get the toc header information */ + if (ioctl(cd->fd,CDROMREADTOCHDR,&toc_header) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + /* read each entry in the toc header */ + for (i = 1; i <= toc_header.cdth_trk1; i++) { + toc_entry.cdte_format = CDROM_MSF; + toc_entry.cdte_track = i; + + if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + + cd->tracks[i].minute = toc_entry.cdte_addr.msf.minute; + cd->tracks[i].second = toc_entry.cdte_addr.msf.second; + cd->tracks[i].frame = toc_entry.cdte_addr.msf.frame; + cd->tracks[i].data_track = (toc_entry.cdte_ctrl == CDROM_DATA_TRACK); + } + + /* read the leadout */ + toc_entry.cdte_track = CDROM_LEADOUT; + toc_entry.cdte_format = CDROM_MSF; + if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { + close(cd->fd); + cd->fd = -1; + return FALSE; + } + cd->tracks[LEADOUT].minute = toc_entry.cdte_addr.msf.minute; + cd->tracks[LEADOUT].second = toc_entry.cdte_addr.msf.second; + cd->tracks[LEADOUT].frame = toc_entry.cdte_addr.msf.frame; + + cd->num_tracks = toc_header.cdth_trk1; + + return TRUE; +} + +gboolean cd_start(struct cd *cd,gint start_track,gint end_track) +{ + struct cdrom_msf msf; + + if (cd->fd == -1) { + return FALSE; + } + + cd_fix_track_range(cd,&start_track,&end_track); + + msf.cdmsf_min0 = cd->tracks[start_track].minute; + msf.cdmsf_sec0 = cd->tracks[start_track].second; + msf.cdmsf_frame0 = cd->tracks[start_track].frame; + + if (end_track == LEADOUT) { + msf.cdmsf_min1 = cd->tracks[end_track].minute; + msf.cdmsf_sec1 = cd->tracks[end_track].second; + msf.cdmsf_frame1 = cd->tracks[end_track].frame; + } else { + msf.cdmsf_min1 = cd->tracks[end_track+1].minute; + msf.cdmsf_sec1 = cd->tracks[end_track+1].second; + msf.cdmsf_frame1 = cd->tracks[end_track+1].frame; + } + + if (ioctl(cd->fd,CDROMPLAYMSF,&msf) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_pause(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMPAUSE,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_resume(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMRESUME,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_stop(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMSTOP,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +/* -1 for error, 0 for not playing, 1 for playing */ +CDStatus cd_status(struct cd *cd) +{ + struct cdrom_subchnl sub_channel; + + if (cd->fd == -1) { + return -1; + } + + sub_channel.cdsc_format = CDROM_MSF; + + if (ioctl(cd->fd,CDROMSUBCHNL,&sub_channel) != 0) { + return -1; + } + + switch (sub_channel.cdsc_audiostatus) { + case CDROM_AUDIO_COMPLETED: + return CD_COMPLETED; + break; + case CDROM_AUDIO_PLAY: + case CDROM_AUDIO_PAUSED: + return CD_PLAYING; + break; + case CDROM_AUDIO_ERROR: + default: + return CD_ERROR; + } +} + +gint cd_current_track(struct cd *cd) +{ + struct cdrom_subchnl sub_channel; + + if (cd->fd == -1) { + return -1; + } + + sub_channel.cdsc_format = CDROM_MSF; + + if (ioctl(cd->fd,CDROMSUBCHNL,&sub_channel) != 0) { + return -1; + } + + + return sub_channel.cdsc_trk; +} + +gboolean cd_close(struct cd *cd) +{ + if (cd->fd == -1) { + return TRUE; + } + + if (close(cd->fd) != 0) { + return FALSE; + } + + cd->fd = -1; + + return TRUE; +} + -- cgit v1.2.1