Added *BSD (and Darwin) ioctl cdaudio playing. Couple bugfixes. 'end-track','current...
authorCharles Schmidt <cbschmid@users.sourceforge.net>
Sun, 28 Jul 2002 22:45:45 +0000 (22:45 +0000)
committerCharles Schmidt <cbschmid@users.sourceforge.net>
Sun, 28 Jul 2002 22:45:45 +0000 (22:45 +0000)
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.

configure.ac
sys/cdrom/Makefile.am
sys/cdrom/gstcdplayer.c
sys/cdrom/gstcdplayer.h
sys/cdrom/gstcdplayer_ioctl.c
sys/cdrom/gstcdplayer_ioctl.h
sys/cdrom/gstcdplayer_ioctl_bsd.h [new file with mode: 0644]
sys/cdrom/gstcdplayer_ioctl_irix.h [new file with mode: 0644]
sys/cdrom/gstcdplayer_ioctl_solaris.h [new file with mode: 0644]

index 7d65315689feafe01bca606bb4a5ab139bba545d..36955fd378e56097e64fdbe1d37d6e5f469d2533 100644 (file)
@@ -285,7 +285,35 @@ GST_CHECK_FEATURE(VGA, [VGA], vgavideosink, [
 dnl *** CDROM Audio ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_CDROM, true)
 GST_CHECK_FEATURE(CDROM, [CDROM Audio], cdrom, [
- AC_CHECK_HEADER(linux/cdrom.h, HAVE_CDROM="yes", HAVE_CDROM="no")
+  AC_CHECK_HEADERS(linux/cdrom.h) dnl linux
+  AC_CHECK_HEADERS(sys/cdio.h) dnl almost everything else
+dnl  AC_CHECK_HEADERS(dmedia/cdaudio.h) dnl irix
+
+  if test "${ac_cv_header_linux_cdrom_h}" = "yes" || test "${ac_cv_header_sys_cdio_h}" = "yes" || test "${ac_cv_header_dmedia_cdaudio_h}" = "yes"; then
+       case "$host" in 
+               *-sun-* | *-*-linux*)
+                       AC_DEFINE(HAVE_CDROM_SOLARIS,, [Define if cdrom access is in Solaris style])
+               ;;
+               *-*-freebsd*)
+                       AC_DEFINE(HAVE_CDROM_BSD,, [Define if cdrom access is in BSD style])
+               ;;
+               *-*-netbsd* | *-*-openbsd*)
+                       AC_DEFINE(HAVE_CDROM_BSD,, [Define if cdrom access is in BSD style])
+                       AC_DEFINE(HAVE_CDROM_BSD_NETBSD,, [Define if cdrom access uses NetBSD variant])
+               ;;
+               *-*darwin*)
+                       AC_DEFINE(HAVE_CDROM_BSD,, [Define if cdrom access is in BSD style])
+                       AC_DEFINE(HAVE_CDROM_BSD_DARWIN,, [Define if cdrom access uses Darwin variant])
+               ;;
+dnl            *-irix-*)
+dnl                    AC_DEFINE(HAVE_CDROM_IRIX,, [Define if cdrom access is in Irix DMedia style])
+dnl            ;;
+    esac
+
+       HAVE_CDROM="yes"
+  else
+       HAVE_CDROM="no"
+  fi
 ])
 
 dnl *** XVideo ***
index a43c1dcb7a10671d9efdaf25d295b3bb6572520d..c3d0600d9d66cb01bd3eb40589704fa230d00ddd 100644 (file)
@@ -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
index 2bbbddb250351df3e673aba7e27d95e4ffe98f7d..7852276f3a807ca9879a1682ba188f49fb053824 100644 (file)
@@ -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;
                                }
                        }
index 5da5527ddb661df6a859d837064acc4482d855ae..39aaaf431616a222ca755f5f6a1d36bccf41a938 100644 (file)
@@ -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);
index 2da746a28a611bee706213a1c77d1836fd2364c2..532d9fc1cb719251cb7ea5f3fdb871e799c92374 100644 (file)
 #include <sys/ioctl.h>
 #include <errno.h>
 
-#include <linux/cdrom.h>
-
-
-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 <linux/cdrom.h>
+#elif define HAVE_SYS_CDIO_H
+#include <sys/cdio.h>
+/*
+irix cdaudio works quite a bit differently than ioctl(), so its not ready
+#elif define HAVE_DMEDIA_CDAUDIO_H
+#include <dmedia/cdaudio.h>
+*/
+#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));
 }
 
+
index 7d96925c8e4c5d64508b60a3922bfa9ca3860c4a..e9fa1a638b8dd688ee2f94eb895cc9a8d41d7abe 100644 (file)
@@ -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 <config.h>
 
 #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 (file)
index 0000000..371c130
--- /dev/null
@@ -0,0 +1,338 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu> 
+
+ * 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 (file)
index 0000000..2f6be35
--- /dev/null
@@ -0,0 +1,109 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu> 
+
+ * 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 (file)
index 0000000..868fb25
--- /dev/null
@@ -0,0 +1,204 @@
+/* gstcdplay
+ * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.edu> 
+
+ * 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;
+}
+