diff --git a/rbcdio/AUTHORS b/rbcdio/AUTHORS new file mode 100644 index 00000000..77332636 --- /dev/null +++ b/rbcdio/AUTHORS @@ -0,0 +1 @@ +R. Bernstein (rocky@gnu.org) diff --git a/rbcdio/Makefile.am b/rbcdio/Makefile.am new file mode 100644 index 00000000..2bef950e --- /dev/null +++ b/rbcdio/Makefile.am @@ -0,0 +1,138 @@ +# $Id: Makefile.am,v 1.1 2006/11/13 05:12:41 rocky Exp $ +# +# Copyright (C) 2006 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA. +# +## Process this file with automake to produce Makefile.in +## which configure then turns into a Makefile ... +## which make can then use to produce stuff. Isn't configuration simple? + +SWIG := @SWIG@ +SWIG_FLAGS := @SWIG_FLAGS@ +SO := @SO@ +EXTCONF = $(top_builddir)/lib/extconf.rb + +# Note rubydio.swg has to come first. +CDIO_SRC = $(top_srcdir)/swig/rubycdio.swg \ + $(top_srcdir)/swig/Makefile \ + $(top_srcdir)/swig/audio.swg \ + $(top_srcdir)/swig/compat.swg \ + $(top_srcdir)/swig/disc.swg \ + $(top_srcdir)/swig/types.swg + +##ISO_SRC = $(top_srcdir)/swig/pyiso9660.swg \ +## $(top_srcdir)/swig/compat.swg \ +## $(top_srcdir)/swig/types.swg + +# TEST_FILES = \ +# test/Makefile \ +# test/cdda.bin \ +# test/cdda.cue \ +# test/cdda.cue \ +# test/cdda.toc \ +# test/cdiotest.py.in \ +# test/isofs-m1.bin \ +# test/isofs-m1.cue \ +# test/isocopy.py.in \ +# test/isotest.py.in + +# DATA_FILES = data/copying.iso data/isofs-m1.cue data/isofs-m1.bin + +# EXAMPLE_FILES = \ +# example/Makefile \ +# example/README \ +# example/audio.py.in \ +# example/cd-read.py.in \ +# example/cdchange.py.in \ +# example/device.py.in +# example/eject.py.in \ +# example/iso1.py.in \ +# example/iso2.py.in \ +# example/iso3.py.in \ +# example/tracks.py.in + +CDIO_C := $(top_builddir)/lib/rubycdio_wrap.c +CDIO_OBJ := $(top_builddir)/lib/rubycdio_wrap.o + +EXTRA_DIST = $(CDIO_SRC) $(CDIO_C) $(EXTCONF) + +dist-hook: + -rm $(top_distdir)/cdio.py $(top_distdir)/rubycdio.rb + + +.PHONY: test check ChangeLog + +all-am: rubycdio$(SO) + +## I just can't take all the crap associated with libtool any more. +## Testing for C++, Fortran, compile and link options to those, +## existence of C headers that aren't used, and that's just in the +## configuration section. +$(CDIO_C): $(CDIO_SRC) + $(SWIG) -o $(CDIO_C) -outdir $(top_builddir) -ruby $(SWIG_FLAGS) $< + +rubycdio$(SO): $(CDIO_C) $(EXTCONF) + (cd lib && $(RUBY) extconf.rb && $(MAKE)) + +$(ISO_C): $(ISO_SRC) + $(SWIG) -o $(ISO_C) -outdir $(top_builddir) -ruby $(SWIG_FLAGS) $< + +clean-generic: + -rm $(CDIO_C) $(CDIO_OBJ) lib/rubycdio$(SO) + +# From libtool documentation amended with guidance from N. Boullis: +# +# 1. Start with version information of `0:0:0' for each libtool library. +# +# 2. It is probably not a good idea to update the version information +# several times between public releases, but rather once per public +# release. (This seems to be more an aesthetic consideration than +# a hard technical one.) +# +# 3. If the library source code has changed at all since the last +# update, then increment REVISION (`C:R:A' becomes `C:R+1:A'). +# +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment CURRENT, and set REVISION to 0. +# +# 5. If any interfaces have been added since the last public release, +# then increment AGE. +# +# 6. If any interfaces have been removed or changed since the last +# public release, then set AGE to 0. A changed interface means an +# incompatibility with previous versions. + +## rubycdio_la_CURRENT := 0 +## rubycdio_la_REVISION := 0 +## rubycdio_la_AGE := 0 + +## rubydio_libnum := $(pycdio_la_CURRENT):$(pycdio_la_REVISION):$(pycdio_la_AGE) + +##install-exec-hook: +## $(LN_S) ${prefix}/lib/libpycdio$(SO).$(pycdio_libnum) ${prefix}/lib/pycdio$(SO) + +# cvs2cl +MAINTAINERCLEANFILES = ChangeLog + +if MAINTAINER_MODE + +ChangeLog: + $(CVS2CL) -W 450 --header $(srcdir)/cvs2cl_header --utc -w -I ChangeLog --usermap $(srcdir)/cvs2cl_usermap -P + +ACLOCAL_AMFLAGS=-I . + +endif diff --git a/rbcdio/NEWS b/rbcdio/NEWS new file mode 100644 index 00000000..9d35a41c --- /dev/null +++ b/rbcdio/NEWS @@ -0,0 +1,5 @@ +0.01 + +- First cut at converting to Ruby + +$Id: NEWS,v 1.1 2006/11/13 05:12:41 rocky Exp $ diff --git a/rbcdio/README b/rbcdio/README new file mode 100644 index 00000000..3e5da030 --- /dev/null +++ b/rbcdio/README @@ -0,0 +1,54 @@ +rubycdio is a Python interface to the CD Input and Control library +(libcdio). You can get the source at the same place as libcdio: + ftp://ftp.gnu.org:/pub/gnu/libcdio/rubycdio-* + +The rubycdio (and libcdio) libraries encapsulate CD-ROM reading and +control. Python programs wishing to be oblivious of the OS- and +device-dependent properties of a CD-ROM can use this library. + +libcdio is rather large and yet may still grow a bit. (UDF support in +libcdio may be on the horizon.) + +What is in rubycdio is incomplete; over time it may grow to completion +depending on various factors: e.g. interest, whether others help +out, whether I get a job at google or some such place that +uses python ;-) + +Sections of libcdio that are currently missing are the (SCSI) MMC +commands, the cdparanoia library, CD-Text handling. Of the audio +controls, I put in those things that didn't require any thought. The +ISO 9660 library is pretty complete, except file "stat" information +which is at present is pretty minimal. + +That said, what's in there is very usable (It contains probably more +access capabilities than what most media players that don't use + +The encapsulation by SWIG is done in two parts. The lower-level python +interface is called rubycdio and is generated by SWIG. + +The more object-oriented module is cdio; it is a Python class that +uses rubycdio. Although rubycdio is perfectly usable on its own, it is +expected that cdio is what most people will use. As rubycdio more +closely models the C interface, it is conceivable (if unlikely) that +diehard libcdio C users who are very familiar with that interface +could prefer that. + +It is probably possible to change the SWIG in such a way to combine +these pieces. However there are the problems. First, I'm not that much +of a SWIG expert. Second it looks as though the resulting SWIG code +would be more complex. Third the separation makes translation very +straight forward to understand and maintain: first get what's in C +into Python as a one-to-one translation. Then we implement some nice +abstraction off of that. The abstraction can be modified without +having to redo the underlying translation. (But the reverse is +generally not true: usually changes to the C-to-python translation, +rubycdio, do result in small, but obvious and straightforward changes to +the abstraction layer cdio.) + +There is much to be done - you want to help out, please do so! + +Standalone documentation is missing although many of the methods, +classes and functions have some document strings. See also the +programs in the example directory. + +$Id: README,v 1.1 2006/11/13 05:12:41 rocky Exp $ diff --git a/rbcdio/autogen.sh b/rbcdio/autogen.sh new file mode 100755 index 00000000..1117d68f --- /dev/null +++ b/rbcdio/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#$Id: autogen.sh,v 1.1 2006/11/13 05:12:41 rocky Exp $ +aclocal -I . +automake --add-missing +autoconf diff --git a/rbcdio/configure.ac b/rbcdio/configure.ac new file mode 100644 index 00000000..07235914 --- /dev/null +++ b/rbcdio/configure.ac @@ -0,0 +1,155 @@ +# Copyright (C) 2006 Rocky Bernstein + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +## Note: the version number (the 2nd parameter in AC_INIT) +## is picked up inside the Python debugger script. + +AC_INIT([rubycdio],[0.01],[libcdio-rubycdio-devel@gnu.org]) + +## +## Check for Python interpreter and make we have a recent version. +## +AC_REVISION([$Id: configure.ac,v 1.1 2006/11/13 05:12:41 rocky Exp $])dnl + +## +## In maintainer mode we produce a ChangeLog +## +AM_MAINTAINER_MODE + +## +## make sure we are using a recent autoconf version +## +AC_PREREQ(2.53) + +AC_ARG_PROGRAM +AC_PROG_CC +AM_INIT_AUTOMAKE + +# +# There are a number of compiler warnings that gcc produces via SWIG code. +# Turn off warnings that are to be expected. +wall='' +AC_TRY_CFLAGS("-Wno-strict-aliasing", cflgs="-Wno-strict-aliasing",) +AC_TRY_CFLAGS("-Wno-unused-function", cflgs="$cflgs -Wno-unused-function",) +CFLAGS="$CFLAGS $cflgs" + +## +## cvs2cl is used to create the ChangeLog when we create a distribution +## +AM_MISSING_PROG(CVS2CL, cvs2cl, $missing_dir) + +## +## SWIG is essential - test for it. +## +AC_PATH_PROG(SWIG, swig, no) +if test "$SWIG" = no ; then + AC_MSG_WARN([Can't find SWIG installed; using C wrapper from distributor.]) + AC_MSG_WARN([Check http://www.swig.org if you want to install SWIG]) +fi + +PKG_CHECK_MODULES(libcdio, libcdio >= 0.76, [], + [AC_MSG_WARN([Required libcdio library, version 0.76 or greater, not found.]) + AC_MSG_ERROR([Please get libcdio from http://www.gnu.org/software/libcdio/ and install it.])]) + +PKG_CHECK_MODULES(libiso9660, libiso9660 >= 0.76, [], + [AC_MSG_WARN([Required libiso9660 library, version 0.76 greater not found.]) + AC_MSG_ERROR([Please get libcdio from http://www.gnu.org/software/libcdio/ and install it.])]) + + +## +## A symbolic links is used to link a name in users PATH to the python +## script. +## +AC_PROG_LN_S + +## +## Automake doesn't get Python's install path correct. So we +## figure it out and set it ourself. +## +AC_ARG_WITH(site-packages, + AC_HELP_STRING([--with-site-packages], + [place to install module]), + PY_PKGDIR) + +AC_ARG_WITH(ruby, + AC_HELP_STRING([--with-ruby], + [set path to Ruby]), + RUBY=$withval,[RUBY=`ruby -e 'require "mkmf"; puts $ruby'`]) + +AC_SUBST(RUBY)dnl + +RUBY_INC=`$RUBY -e 'puts "-I " + $:.join(" -I ")'` +AC_SUBST(RUBY_INC)dnl + +AC_CANONICAL_HOST +case $host_os in + cygwin* | mingw* | pw32*) + SO='.dll' + CFLAGS="$CFLAGS -DUSE_DL_IMPORT" + # Should we check the 32-ness? + SWIG_FLAGS=-DNEED_LONG + if test "$GCC" = yes; then + LDSHARED="$CC -shared -Wl,--enable-auto-image-base" + else + if test "cl" = $CC ; then + # Microsoft Visual C++ (MSVC) + LDSHARED="$CC -nologo -LD" + else + # Unknown compiler try gcc approach + LDSHARED="$CC -shared" + fi + fi + ;; + linux*) + SO=.so + LDSHARED="gcc -shared" + ;; + darwin6*|darwin7*|darwin8*) + SO=.so + LDSHARED="cc -bundle -undefined suppress -flat_namespace" + ;; + solaris*) + SO=.so + LDSHARED="gcc -shared" + AC_TRY_CFLAGS("-fPIC", cflgs="$cflgs -fPIC",) + CFLAGS="$CFLAGS $cflgs" + ;; + *) + AC_TRY_CFLAGS("-fPIC", cflgs="$cflgs -fPIC",) + CFLAGS="$CFLAGS $cflgs" + SO='.so' + PYTHON_LIBS= +esac +AC_SUBST(SO) +AC_SUBST(RUBY_LIBS) +AC_SUBST(LDSHARED) +AC_SUBST(SWIG_FLAGS) + +## +## Test program needs location of pycdio shared library +## This is a hack, but I at present I'm not sure what the best thing to +## do is. +RUBYCDIO_LIBDIR=`pwd` +AC_SUBST(RUBYCDIO_LIBDIR)dnl + +## +## Produced derived files. +## +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT + diff --git a/rbcdio/example/device.rb b/rbcdio/example/device.rb new file mode 100644 index 00000000..b49d9053 --- /dev/null +++ b/rbcdio/example/device.rb @@ -0,0 +1,72 @@ +#!/usr/bin/env ruby +#$Id: device.rb,v 1.1 2006/11/13 05:12:43 rocky Exp $ +# Program to show CD-ROM device information +# +# Copyright (C) 2006 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +$: << File.dirname(__FILE__) + '/../lib/' +require "cdio" + +# Return sorted keys of a dictionary. +# There's probably an easier way to do this that I'm not aware of. +def sort_dict_keys(dict) + keys=dict.keys() + keys.sort() + return keys +end + +if ARGV.length() > 0 + begin + drive_name = ARGV[0] + d = Device.new(drive_name) + rescue IOError + puts "Problem opening CD-ROM: %s" % drive_name + exit(1) + end +else + begin + d = Device.new("", Rubycdio::DRIVER_UNKNOWN) + drive_name = d.get_device() + rescue IOError: + puts "Problem finding a CD-ROM" + exit(1) + end +end + +# Should there should be no "ok"? +ok, vendor, model, release = d.get_hwinfo() + +puts "drive: %s, vendor: %s, model: %s, release: %s" \ + % [drive_name, vendor, model, release] + +read_cap, write_cap, misc_cap = d.get_drive_cap() +puts "Drive Capabilities for %s..." % drive_name + +# FIXME +# puts "\n".join(cap for cap in sort_dict_keys(read_cap) + +# sort_dict_keys(write_cap) + sort_dict_keys(misc_cap)) + +puts "\nDriver Availabiliity..." +drivers.each_pair { |driver_name, driver_id| + begin + if Rubycdio::have_driver(driver_id) == 1: + puts "Driver %s is installed." % driver_name + end + rescue ValueError + end +} +d.close() diff --git a/rbcdio/example/eject.rb b/rbcdio/example/eject.rb new file mode 100755 index 00000000..12981bf8 --- /dev/null +++ b/rbcdio/example/eject.rb @@ -0,0 +1,60 @@ +#!/usr/bin/env ruby +#$Id: eject.rb,v 1.1 2006/11/13 05:12:43 rocky Exp $ +# Program to Eject and close CD-ROM drive +# +# Copyright (C) 2006 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +$: << File.dirname(__FILE__) + '/../lib/' +require "cdio" + +if ARGV.length() > 0 + begin + drive_name=@ARGV[1] + d = Device.new(drive_name) + rescue IOError + print "Problem opening CD-ROM: %s" % drive_name + exit 1 + end +else + begin + d = Device.new(nil, Rubycdio::DRIVER_UNKNOWN) + drive_name = d.get_device() + rescue IOError + print "Problem finding a CD-ROM" + exit 1 + end +end + +begin + puts "Ejecting CD in drive %s" % drive_name + d.eject_media() + begin + Rubycdio::close_tray(drive_name) + puts "Closed tray of CD-ROM drive %s" % drive_name + rescue DeviceException + puts "Closing tray of CD-ROM drive %s failed" % drive_name + end + +rescue DriverUnsupportedError + puts "Eject not supported for %s" % drive_name +rescue DeviceException + puts "Eject of CD-ROM drive %s failed" % drive_name +end + + + + diff --git a/rbcdio/example/tracks.rb b/rbcdio/example/tracks.rb new file mode 100755 index 00000000..0600b56c --- /dev/null +++ b/rbcdio/example/tracks.rb @@ -0,0 +1,79 @@ +#!/usr/bin/env ruby +#$Id: tracks.rb,v 1.1 2006/11/13 05:12:43 rocky Exp $ +# Program to show CD information +# +# Copyright (C) 2006 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +$: << File.dirname(__FILE__) + '/../lib/' +require "cdio" + +if ARGV.length() > 0 + begin + d = Device.new(@ARGV[1]) + rescue IOError + puts "Problem opening CD-ROM: %s" % @ARGV[1] + exit(1) + end +else + begin + d = Device.new("", Rubycdio::DRIVER_UNKNOWN) + rescue IOError + puts "Problem finding a CD-ROM" + exit(1) + end +end + +t = d.get_first_track() +if not t + puts "Problem getting first track" + exit(2) +end + +first_track = t.track +num_tracks = d.get_num_tracks() +last_track = first_track+num_tracks-1 + +begin + last_session = d.get_last_session() + puts "CD-ROM %s has %d track(s) and %d session(s)." % + [d.get_device(), d.get_num_tracks(), last_session] +rescue DriverUnsupportedError: + puts "CD-ROM %s has %d track(s). " % [d.get_device(), d.get_num_tracks()] +end + +puts "Track format is %s." % d.get_disc_mode() + +mcn = d.get_mcn() +if mcn + puts "Media Catalog Number: %s" % mcn +end + +puts "%3s: %-6s %s" % ["#", "LSN", "Format"] +i=first_track +while (i <= last_track): + begin + t = d.get_track(i) + puts "%3d: %06u %-6s %s" % [t.track, t.get_lsn(), + t.get_msf(), t.get_format()] + rescue TrackError + end + i += 1 +end + +puts "%3X: %06u leadout" \ + % [Rubycdio::CDROM_LEADOUT_TRACK, d.get_disc_last_lsn()] +d.close() diff --git a/rbcdio/lib/cdio.rb b/rbcdio/lib/cdio.rb new file mode 100644 index 00000000..5a8fca4e --- /dev/null +++ b/rbcdio/lib/cdio.rb @@ -0,0 +1,923 @@ +#!/usr/bin/env ruby +# $Id: cdio.rb,v 1.1 2006/11/13 05:12:42 rocky Exp $ +# +# Copyright (C) 2006 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA. +# + +# The CD Input and Control library (pycdio) encapsulates CD-ROM +# reading and control. Applications wishing to be oblivious of the OS- +# and device-dependent properties of a CD-ROM can use this library. + +require "rubycdio" + +# General device or driver exceptions +class DeviceException < Exception +end + +class DriverError < DeviceException; end +class DriverUnsupportedError < DeviceException; end +class DriverUninitError < DeviceException; end +class DriverNotPermittedError < DeviceException; end +class DriverBadParameterError < DeviceException; end +class DriverBadPointerError < DeviceException; end +class NoDriverError < DeviceException; end + +class TrackError < DeviceException; end + + +# Note: the keys below match those the names returned by +# cdio_get_driver_name() +def drivers() + return { + "Unknown" => Rubycdio::DRIVER_UNKNOWN, + "AIX" => Rubycdio::DRIVER_AIX, + "BSDI" => Rubycdio::DRIVER_BSDI, + "FreeBSD" => Rubycdio::DRIVER_FREEBSD, + "GNU/Linux" => Rubycdio::DRIVER_LINUX, + "Solaris" => Rubycdio::DRIVER_SOLARIS, + "OS X" => Rubycdio::DRIVER_OSX, + "WIN32" => Rubycdio::DRIVER_WIN32, + "CDRDAO" => Rubycdio::DRIVER_CDRDAO, + "BINCUE" => Rubycdio::DRIVER_BINCUE, + "NRG" => Rubycdio::DRIVER_NRG, + "device" => Rubycdio::DRIVER_DEVICE + } +end + + +read_mode2blocksize = { + :READ_MODE_AUDIO => Rubycdio::CD_FRAMESIZE_RAW, + :READ_MODE_M1F1 => Rubycdio::M2RAW_SECTOR_SIZE, + :READ_MODE_M1F2 => Rubycdio::CD_FRAMESIZE, + :READ_MODE_M2F1 => Rubycdio::M2RAW_SECTOR_SIZE, + :READ_MODE_M2F2 => Rubycdio::CD_FRAMESIZE +} + + +# Raise a Driver Error exception on error as determined by drc +def __possibly_raise_exception__(drc, msg=nil) + if drc==Rubycdio::DRIVER_OP_SUCCESS + return + end + if drc==Rubycdio::DRIVER_OP_ERROR + raise DriverError + end + if drc==Rubycdio::DRIVER_OP_UNINIT + raise DriverUninitError + end + if drc==Rubycdio::DRIVER_OP_UNSUPPORTED + raise DriverUnsupportedError + end + if drc==Rubycdio::DRIVER_OP_NOT_PERMITTED + raise DriverUnsupportedError + end + if drc==Rubycdio::DRIVER_OP_BAD_PARAMETER + raise DriverBadParameterError + end + if drc==Rubycdio::DRIVER_OP_BAD_POINTER + raise DriverBadPointerError + end + if drc==Rubycdio::DRIVER_OP_NO_DRIVER + raise NoDriverError + end + raise DeviceException('unknown exception %d' % drc) +end + +# close_tray(drive=nil, driver_id=DRIVER_UNKNOWN) -> driver_id +# +# close media tray in CD drive if there is a routine to do so. +# The driver id is returned. A DeviceException is thrown on error. +def close_tray(drive=nil, driver_id=Rubycdio::DRIVER_UNKNOWN) + drc, found_driver_id = Rubycdio::close_tray(drive, driver_id) + __possibly_raise_exception__(drc) + return found_driver_id +end + +# get_default_device_driver(driver_id=Rubycdio::DRIVER_DEVICE) +# ->[device, driver] +# +# Return a string containing the default CD device if none is +# specified. if driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE +# then one set the default device for that. +# +# nil is returned as the device if we couldn't get a default +# device. +def get_default_device_driver(driver_id=Rubycdio::DRIVER_DEVICE) + return Rubycdio::get_default_device_driver(driver_id) +end + +# get_devices(driver_id)->[device1, device2, ...] +# +# Get an list of device names. +def get_devices(driver_id=nil) + return Rubycdio::get_devices(driver_id) +end + +# get_devices_ret(driver_id)->[device1, device2, ... driver_id] +# +# Like get_devices, but return the p_driver_id which may be different +# from the passed-in driver_id if it was Rubycdio::DRIVER_DEVICE or +# Rubycdio::DRIVER_UNKNOWN. The return driver_id may be useful because +# often one wants to get a drive name and then *open* it +# afterwards. Giving the driver back facilitates this, and speeds things +# up for libcdio as well. +def get_devices_ret(driver_id=nil) + devices = Rubycdio::get_devices_ret(driver_id) +end + +# get_devices_with_cap(capabilities, any=false)->[device1, device2...] +# Get an array of device names in search_devices that have at least +# the capabilities listed by the capabities parameter. +# +# If any is false then every capability listed in the +# extended portion of capabilities (i.e. not the basic filesystem) +# must be satisified. If any is true, then if any of the +# capabilities matches, we call that a success. +# +# To find a CD-drive of any type, use the mask Rubycdio::CDIO_FS_MATCH_ALL. +# +# The array of device names is returned or NULL if we couldn't get a +# default device. It is also possible to return a non NULL but after +# dereferencing the the value is NULL. This also means nothing was +# found. +def get_devices_with_cap(capabilities, any=false) + # FIXME: SWIG code is not removing a parameter properly, hence the [1:] + # at the end + return Rubycdio::get_devices_with_cap(capabilities, any) +end + +# get_devices_with_cap(capabilities, any=false) +# [device1, device2..., driver_id] +# +# Like cdio_get_devices_with_cap but we return the driver we found +# as well. This is because often one wants to search for kind of drive +# and then *open* it afterwards. Giving the driver back facilitates this, +# and speeds things up for libcdio as well. +def get_devices_with_cap_ret(capabilities, any=false) + # FIXME: SWIG code is not removing a parameter properly, hence the [1:] + # at the end + return Rubycdio::get_devices_with_cap_ret(capabilities, any) +end + +# have_driver(driver_id) -> bool +# +# Return true if we have driver driver_id. +def have_driver(driver_id) + if driver_id.class == Fixnum + return Rubycdio::have_driver(driver_id) + elsif driver_id.class == String and drivers.member?(driver_id) + ret = Rubycdio::have_driver(drivers[driver_id]) + if ret == 0 then return false end + if ret == 1 then return true end + raise ValueError('internal error: driver id came back %d' % ret) + else + raise ValueError('need either a number or string driver id') + end +end + +# binfile?(binfile_name)->cue_name +# +# Determine if binfile_name is the BIN file part of a CDRWIN CD +# disk image. +# +# Return the corresponding CUE file if bin_name is a BIN file or +# nil if not a BIN file. +def binfile?(binfile_name) + return Rubycdio::is_binfile(binfile_name) +end + +# cuefile?(cuefile_name)->bin_name +# +# Determine if cuefile_name is the CUE file part of a CDRWIN CD +# disk image. +# +# Return the corresponding BIN file if bin_name is a CUE file or +# nil if not a CUE file. +def cuefile?(cuefile_name) + return Rubycdio::is_cuefile(cuefile_name) +end + +# is_device(source, driver_id=Rubycdio::DRIVER_UNKNOWN)->bool +# Return true if source refers to a real hardware CD-ROM. +def device?(source, driver_id=Rubycdio::DRIVER_UNKNOWN) + if not driver_id then driver_id=Rubycdio::DRIVER_UNKNOWN end + return Rubycdio::is_device(source, driver_id) +end + +# nrg?(nrgfile_name)->bool +# +# Determine if nrgfile_name is a Nero CD disc image +def nrg?(nrgfile_name) + return Rubycdio::is_nrg(nrgfile_name) +end + +# tocfile?(tocfile_name)->bool +# +# Determine if tocfile_name is a cdrdao CD disc image +def tocfile?(tocfile_name) + return Rubycdio::is_tocfile(tocfile_name) +end + +# Convert bit mask for miscellaneous drive properties +# into a dictionary of drive capabilities +def convert_drive_cap_misc(bitmask) + result={} + if bitmask & Rubycdio::DRIVE_CAP_ERROR + result[:DRIVE_CAP_ERROR] = true + end + if bitmask & Rubycdio::DRIVE_CAP_UNKNOWN + result[:DRIVE_CAP_UNKNOWN] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_CLOSE_TRAY + result[:DRIVE_CAP_MISC_CLOSE_TRAY] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_EJECT + result[:DRIVE_CAP_MISC_EJECT] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_LOCK + result['DRIVE_CAP_MISC_LOCK'] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_SELECT_SPEED + result[:DRIVE_CAP_MISC_SELECT_SPEED] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_SELECT_DISC + result[:DRIVE_CAP_MISC_SELECT_DISC] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_MULTI_SESSION + result[:DRIVE_CAP_MISC_MULTI_SESSION] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_MEDIA_CHANGED + result[:DRIVE_CAP_MISC_MEDIA_CHANGED] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_RESET + result[:DRIVE_CAP_MISC_RESET] = true + end + if bitmask & Rubycdio::DRIVE_CAP_MISC_FILE + result[:DRIVE_CAP_MISC_FILE] = true + end + return result +end + +# Convert bit mask for drive read properties +# into a dictionary of drive capabilities +def convert_drive_cap_read(bitmask) + result={} + if bitmask & Rubycdio::DRIVE_CAP_READ_AUDIO + result[:DRIVE_CAP_READ_AUDIO] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_CD_DA + result[:DRIVE_CAP_READ_CD_DA] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_CD_G + result[:DRIVE_CAP_READ_CD_G] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_CD_R + result[:DRIVE_CAP_READ_CD_R] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_CD_RW + result[:DRIVE_CAP_READ_CD_RW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_R + result[:DRIVE_CAP_READ_DVD_R] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_PR + result[:DRIVE_CAP_READ_DVD_PR] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RAM + result[:DRIVE_CAP_READ_DVD_RAM] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_ROM + result[:DRIVE_CAP_READ_DVD_ROM] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RW + result[:DRIVE_CAP_READ_DVD_RW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RPW + result[:DRIVE_CAP_READ_DVD_RPW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_C2_ERRS + result[:DRIVE_CAP_READ_C2_ERRS] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_MODE2_FORM1 + result[:DRIVE_CAP_READ_MODE2_FORM1] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_MODE2_FORM2 + result[:DRIVE_CAP_READ_MODE2_FORM2] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_MCN + result[:DRIVE_CAP_READ_MCN] = true + end + if bitmask & Rubycdio::DRIVE_CAP_READ_ISRC + result[:DRIVE_CAP_READ_ISRC] = true + end + return result +end + +# Convert bit mask for drive write properties +# into a dictionary of drive capabilities +def convert_drive_cap_write(bitmask) + result={} + if bitmask & Rubycdio::DRIVE_CAP_WRITE_CD_R + result[:DRIVE_CAP_WRITE_CD_R] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_CD_RW + result[:DRIVE_CAP_WRITE_CD_RW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_R + result[:DRIVE_CAP_WRITE_DVD_R] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_PR + result[:DRIVE_CAP_WRITE_DVD_PR] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RAM + result[:DRIVE_CAP_WRITE_DVD_RAM] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RW + result[:DRIVE_CAP_WRITE_DVD_RW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RPW + result[:DRIVE_CAP_WRITE_DVD_RPW] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_MT_RAINIER + result[:DRIVE_CAP_WRITE_MT_RAINIER] = true + end + if bitmask & Rubycdio::DRIVE_CAP_WRITE_BURN_PROOF + result[:DRIVE_CAP_WRITE_BURN_PROOF] = true + end + return result +end + +# CD Input and control class for discs/devices +class Device + + def initialize(source=nil, driver_id=nil, + access_mode=nil) + @cd = nil + if source or driver_id + open(source, driver_id, access_mode) + end + end + + # audio_pause(cdio)->status + # Pause playing CD through analog output. + # A DeviceError exception may be raised. + def audio_pause() + drc=Rubycdio::audio_pause(@cd) + __possibly_raise_exception__(drc) + end + + # auto_play_lsn(cdio, start_lsn, end_lsn)->status + # + # Playing CD through analog output at the given lsn to the ending lsn + # A DeviceError exception may be raised. + def audio_play_lsn(start_lsn, end_lsn) + drc=Rubycdio::audio_play_lsn(@cd, start_lsn, end_lsn) + __possibly_raise_exception__(drc) + end + + # audio_resume(cdio)->status + # Resume playing an audio CD through the analog interface. + # A DeviceError exception may be raised. + def audio_resume() + drc=Rubycdio::audio_resume(@cd) + __possibly_raise_exception__(drc) + end + + # audio_stop(cdio)->status + # Stop playing an audio CD through the analog interface. + # A DeviceError exception may be raised. + def audio_stop() + drc=Rubycdio::audio_stop(@cd) + __possibly_raise_exception__(drc) + end + + # close() + # Free resources associated with p_cdio. Call this when done using + # using CD reading/control operations for the current device. + def close() + if @cd + Rubycdio::close(@cd) + else + puts "***No object to close" + end + @cd=nil + end + + # eject_media() + # Eject media in CD drive if there is a routine to do so. + # A DeviceError exception may be raised. + def eject_media() + drc=Rubycdio::eject_media(@cd) + @cd = nil + __possibly_raise_exception__(drc) + end + + # eject_media_drive(drive=nil) + # Eject media in CD drive if there is a routine to do so. + # An exception is thrown on error. + def eject_media_drive(drive=nil) + ### FIXME: combine into above by testing if drive is the string + ### nil versus drive = Rubycdio::DRIVER_UNKNOWN + Rubycdio::eject_media_drive(drive) + end + + # get_arg(key)->string + # Get the value associatied with key. + def get_arg(key) + return Rubycdio::get_arg(@cd, key) + end + + # get_device()->str + # Get the default CD device. + # If we haven't initialized a specific device driver), + # then find a suitable one and return the default device for that. + # In some situations of drivers or OS's we can't find a CD device if + # there is no media in it and it is possible for this routine to return + # nil even though there may be a hardware CD-ROM. + def get_device() + if @cd + return Rubycdio::get_arg(@cd, "source") + end + return Rubycdio::get_device(@cd) + end + + # get_disc_last_lsn()->int + # Get the LSN of the end of the CD + # + # DriverError and IOError may raised on error. + def get_disc_last_lsn() + lsn = Rubycdio::get_disc_last_lsn(@cd) + if lsn == Rubycdio::INVALID_LSN: + raise DriverError('Invalid LSN returned') + end + return lsn + end + + # get_disc_mode(p_cdio) -> str + # + # Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc. + # that we've got. The notion of 'CD' is extended a little to include + # DVD's. + def get_disc_mode() + return Rubycdio::get_disc_mode(@cd) + end + + # get_drive_cap()->(read_cap, write_cap, misc_cap) + # + # Get drive capabilities of device. + # + # In some situations of drivers or OS's we can't find a CD + # device if there is no media in it. In this situation + # capabilities will show up as empty even though there is a + # hardware CD-ROM. get_drive_cap_dev()->(read_cap, write_cap, + # misc_cap) + # + # Get drive capabilities of device. + # + # In some situations of drivers or OS's we can't find a CD + # device if there is no media in it. In this situation + # capabilities will show up as empty even though there is a + # hardware CD-ROM. + def get_drive_cap() + b_read_cap, b_write_cap, b_misc_cap = Rubycdio::get_drive_cap(@cd) + return [convert_drive_cap_read(b_read_cap), + convert_drive_cap_write(b_write_cap), + convert_drive_cap_misc(b_misc_cap)] + end + + def get_drive_cap_dev(device=nil) + ### FIXME: combine into above by testing on the type of device. + b_read_cap, b_write_cap, b_misc_cap = + Rubycdio::get_drive_cap_dev(device); + return [convert_drive_cap_read(b_read_cap), + convert_drive_cap_write(b_write_cap), + convert_drive_cap_misc(b_misc_cap)] + end + + # get_driver_name()-> string + # + # return a string containing the name of the driver in use. + # + # An IOError exception is raised on error. + def get_driver_name() + return Rubycdio::get_driver_name(@cd) + end + + # get_driver_id()-> int + # + # Return the driver id of the driver in use. + # if object has not been initialized or is nil, + # return Rubycdio::DRIVER_UNKNOWN. + def get_driver_id() + return Rubycdio::get_driver_id(@cd) + end + + # get_first_track()->Track + # + # return a Track object of the first track. nil is returned + # if there was a problem. + def get_first_track() + track = Rubycdio::get_first_track_num(@cd) + if track == Rubycdio::INVALID_TRACK + return nil + end + return Track.new(@cd, track) + end + + # get_hwinfo()->[vendor, model, release] + # Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. + def get_hwinfo() + return Rubycdio::get_hwinfo(@cd) + end + + # get_joliet_level()->int + # + # Return the Joliet level recognized for cdio. + # This only makes sense for something that has an ISO-9660 + # filesystem. + def get_joliet_level() + return Rubycdio::get_joliet_level(@cd) + end + + # get_last_session() -> int + # Get the LSN of the first track of the last session of on the CD. + # An exception is thrown on error. + def get_last_session() + drc, session = Rubycdio::get_last_session(@cd) + __possibly_raise_exception__(drc) + return session + end + + # get_last_track()->Track + # + # return a Track object of the first track. nil is returned + # if there was a problem. + def get_last_track() + track = Rubycdio::get_last_track_num(@cd) + if track == Rubycdio::INVALID_TRACK + return nil + end + return Track.new(@cd, track) + end + + # get_mcn() -> str + # + # Get the media catalog number (MCN) from the CD. + def get_mcn() + return Rubycdio::get_mcn(@cd) + end + + # get_media_changed() -> bool + # + # Find out if media has changed since the last call. + # Return true if media has changed since last call. An exception + # Error is given on error. + def get_media_changed() + drc = Rubycdio::get_media_changed(@cd) + if drc == 0 then return false end + if drc == 1 then return true end + __possibly_raise_exception__(drc) + raise DeviceException('Unknown return value %d' % drc) + end + + # get_num_tracks()->int + # + # Return the number of tracks on the CD. + # A TrackError or IOError exception may be raised on error. + def get_num_tracks() + track = Rubycdio::get_num_tracks(@cd) + if track == Rubycdio::INVALID_TRACK: + raise TrackError('Invalid track returned') + end + return track + end + + # get_track(track_num)->track + # + # Return a track object for the given track number. + def get_track(track_num) + return Track.new(@cd, track_num) + end + + # get_track_for_lsn(lsn)->Track + # + # Find the track which contains lsn. + # nil is returned if the lsn outside of the CD or + # if there was some error. + # + # If the lsn is before the pregap of the first track, + # A track object with a 0 track is returned. + # Otherwise we return the track that spans the lsn. + def get_track_for_lsn(lsn) + track = Rubycdio::get_last_track_num(@cd) + if track == Rubycdio::INVALID_TRACK: + return nil + end + return Track.new(@cd, track) + end + + # have_ATAPI()->bool + # return true if CD-ROM understand ATAPI commands. + def have_ATAPI() + return Rubycdio::have_ATAPI(@cd) + end + + # lseek(offset, whence)->int + # Reposition read offset + # Similar to (if not the same as) libc's fseek() + # + # cdio is object to get adjested, offset is amount to seek and + # whence is like corresponding parameter in libc's lseek, e.g. + # it should be SEEK_SET or SEEK_END. + # + # the offset is returned or -1 on error. + def lseek(offset, whence) + return Rubycdio::lseek(@cd, offset, whence) + end + + # open(source=nil, driver_id=Rubycdio::DRIVER_UNKNOWN, + # access_mode=nil) + # + # Sets up to read from place specified by source, driver_id and + # access mode. This should be called before using any other routine + # except those that act on a CD-ROM drive by name. + # + # If nil is given as the source, we'll use the default driver device. + # If nil is given as the driver_id, we'll find a suitable device driver. + # + # If device object was, previously opened it is closed first. + # + # Device is opened so that subsequent operations can be performed. + def open(source=nil, driver_id=Rubycdio::DRIVER_UNKNOWN, + access_mode=nil) + if not driver_id + driver_id=Rubycdio::DRIVER_UNKNOWN + end + if not source + source = '' + end + if not access_mode + access_mode = '' + end + if @cd + close() + end + @cd = Rubycdio::open_cd(source, driver_id, access_mode) + end + + # read(size)->[size, data] + # + # Reads the next size bytes. + # Similar to (if not the same as) libc's read() + # + # The number of bytes read and the data is returned. + # A DeviceError exception may be raised. + def read(size) + size, data = Rubycdio::read_cd(@cd, size) + __possibly_raise_exception__(size) + return [size, data] + end + + # read_data_blocks(blocks, lsn, blocks=1)->[size, data] + # + # Reads a number of data sectors (AKA blocks). + # + # lsn is sector to read, bytes is the number of bytes. + # A DeviceError exception may be raised. + def read_data_blocks(lsn, blocks=1) + size = Rubycdio::ISO_BLOCKSIZE*blocks + size, data = Rubycdio::read_data_bytes(@cd, size, lsn, + Rubycdio::ISO_BLOCKSIZE) + if size < 0 + __possibly_raise_exception__(size) + end + return [size, data] + end + + # read_sectors(lsn, read_mode, blocks=1)->[blocks, data] + # Reads a number of sectors (AKA blocks). + # + # lsn is sector to read, bytes is the number of bytes. + # + # If read_mode is Rubycdio::MODE_AUDIO, the return buffer size will be + # truncated to multiple of Rubycdio::CDIO_FRAMESIZE_RAW i_blocks bytes. + # + # If read_mode is Rubycdio::MODE_DATA, buffer will be truncated to a + # multiple of Rubycdio::ISO_BLOCKSIZE, Rubycdio::M1RAW_SECTOR_SIZE or + # Rubycdio::M2F2_SECTOR_SIZE bytes depending on what mode the data is in. + # + # If read_mode is Rubycdio::MODE_M2F1, buffer will be truncated to a + # multiple of Rubycdio::M2RAW_SECTOR_SIZE bytes. + # + # If read_mode is Rubycdio::MODE_M2F2, the return buffer size will be + # truncated to a multiple of Rubycdio::CD_FRAMESIZE bytes. + # + # The number of bytes read and the data is returned. + # A DeviceError exception may be raised. + def read_sectors(lsn, read_mode, blocks=1) + begin + blocksize = read_mode2blocksize[read_mode] + size = blocks * blocksize + rescue KeyError + raise DriverBadParameterError('Bad read mode %d' % read_mode) + end + size, data = Rubycdio::read_sectors(@cd, size, lsn, read_mode) + if size < 0 + __possibly_raise_exception__(size) + end + blocks = size / blocksize + return [blocks, data] + end + + # set_blocksize(blocksize) + # Set the blocksize for subsequent reads. + # An exception is thrown on error. + def set_blocksize(blocksize) + drc = Rubycdio::set_blocksize(@cd, blocksize) + __possibly_raise_exception__(drc) + end + + # set_speed(speed) + # Set the drive speed. An exception is thrown on error. + def set_speed(speed) + drc = Rubycdio::set_speed(@cd, speed) + __possibly_raise_exception__(drc) + end +end # Device + +# CD Input and control track class +class Track + + def initialize(device, track_num) + + if track_num.class != Fixnum + raise TrackError('track number parameter is not an integer') + end + @track = track_num + + # See if the device parameter is a string or + # a device object. + if device.class == String + @device = Device.new(device) + else + @device = device + end + end + + # get_audio_channels(track)->int + # + # Return number of channels in track: 2 or 4 + # Not meaningful if track is not an audio track. + # An exception can be raised on error. + def get_audio_channels() + channels = Rubycdio::get_track_channels(@device, @track) + if -2 == channels + raise DriverUnsupportedError + elsif -1 == channels + raise TrackError + else + return channels + end + end + + # get_copy_permit(track)->int + # + # Return copy protection status on a track. Is this meaningful + # not an audio track? + def get_copy_permit() + if Rubycdio::get_track_copy_permit(@device, @track): + return "OK" + else + return "no" + end + end + + # get_format()->format + # Get the format (e.g. 'audio', 'mode2', 'mode1') of track. + def get_format() + return Rubycdio::get_track_format(@device, @track) + end + + # get_last_lsn()->lsn + # + # Return the ending LSN for a track + # A TrackError or IOError exception may be raised on error. + def get_last_lsn() + lsn = Rubycdio::get_track_last_lsn(@device, @track) + if lsn == Rubycdio::INVALID_LSN + raise TrackError('Invalid LSN returned') + end + return lsn + end + + # get_lsn()->lba + # + # Return the starting LBA for a track + # A TrackError exception is raised on error. + def get_lba() + lba = Rubycdio::get_track_lba(@device, @track) + if lba == Rubycdio::INVALID_LBA + raise TrackError('Invalid LBA returned') + end + return lba + end + + # get_lsn()->lsn + # + # Return the starting LSN for a track + # A TrackError exception is raised on error. + def get_lsn() + lsn = Rubycdio::get_track_lsn(@device, @track) + if lsn == Rubycdio::INVALID_LSN: + raise TrackError('Invalid LSN returned') + end + return lsn + end + + # get_msf()->str + # + # Return the starting MSF (minutes/secs/frames) for track number track. + # Track numbers usually start at something greater than 0, usually 1. + # + # Returns string of the form mm:ss:ff if all good, or string nil on + # error. + def get_msf() + return Rubycdio::get_track_msf(@device, @track) + end + + # get_preemphaisis()->result + # + # Get linear preemphasis status on an audio track. + # This is not meaningful if not an audio track? + # A TrackError exception is raised on error. + def get_preemphasis() + rc = Rubycdio::get_track_preemphasis(@device, @track) + if rc == Rubycdio::TRACK_FLAG_FALSE: + return 'none' + elsif rc == Rubycdio::TRACK_FLAG_TRUE: + return 'preemphasis' + elsif rc == Rubycdio::TRACK_FLAG_UNKNOWN: + return 'unknown' + else + raise TrackError('Invalid return value %d' % d) + end + end + + # get_track_sec_count()->int + # + # Get the number of sectors between this track an the next. This + # includes any pregap sectors before the start of the next track. + # Track numbers usually start at something + # greater than 0, usually 1. + # + # A TrackError exception is raised on error. + def get_track_sec_count() + sec_count = Rubycdio::get_track_sec_count(@device, @track) + if sec_count == 0 + raise TrackError + end + return sec_count + end + + # green?(track) -> bool + # + # Return true if we have XA data (green, mode2 form1) or + # XA data (green, mode2 form2). That is track begins: + # sync - header - subheader + # 12 4 - 8 + def green?() + return Rubycdio::is_track_green(@device, @track) + end + + # set_track(track_num) + # + # Set a new track number. + def set_track(track_num) + @track = track_num + end + + # Return the track track number. + def track() + @track + end + end # Track + +# +# Local variables: +# mode: Ruby +# End: diff --git a/rbcdio/lib/extconf.rb b/rbcdio/lib/extconf.rb new file mode 100644 index 00000000..fb5ae3c0 --- /dev/null +++ b/rbcdio/lib/extconf.rb @@ -0,0 +1,4 @@ +require 'mkmf' +dir_config('rubycdio') +$libs = append_library($libs, "cdio") +create_makefile('rubycdio') diff --git a/rbcdio/rubycdio.m4 b/rbcdio/rubycdio.m4 new file mode 100644 index 00000000..87d5143c --- /dev/null +++ b/rbcdio/rubycdio.m4 @@ -0,0 +1,14 @@ +dnl AC_TRY_CFLAGS (CFLAGS, [ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check if $CC supports a given set of cflags +AC_DEFUN([AC_TRY_CFLAGS], + [AC_MSG_CHECKING([if $CC supports $1 flags]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$1" + AC_TRY_COMPILE([],[],[ac_cv_try_cflags_ok=yes],[ac_cv_try_cflags_ok=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_try_cflags_ok]) + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + ifelse([$2],[],[:],[$2]) + else + ifelse([$3],[],[:],[$3]) + fi]) diff --git a/rbcdio/swig/Makefile b/rbcdio/swig/Makefile new file mode 100644 index 00000000..5257c0f7 --- /dev/null +++ b/rbcdio/swig/Makefile @@ -0,0 +1,7 @@ +#============================================================= +# $Id: Makefile,v 1.1 2006/11/13 05:12:42 rocky Exp $ +#============================================================= +# Whatever it is you want to do, it should be handled by the +# by the main (parent) Makefile. So reissue make from there. +all %: + $(MAKE) -C .. $@ diff --git a/rbcdio/swig/audio.swg b/rbcdio/swig/audio.swg new file mode 100644 index 00000000..8b13e65d --- /dev/null +++ b/rbcdio/swig/audio.swg @@ -0,0 +1,63 @@ +/* -*- c -*- + $Id: audio.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** NOTE: THIS IS THE EASILY CONVERTED SUBSET OF LIBCDIO WE CAN DO. **/ + +/* See for more extensive documentation. */ + +%rename cdio_audio_pause audio_pause; +%feature("autodoc", +"audio_pause(cdio)->status + +Pause playing CD through analog output."); +driver_return_code_t cdio_audio_pause (CdIo_t *p_cdio); + + +%feature("autodoc", +"auto_play_lsn(cdio, start_lsn, end_lsn)->status + +Playing CD through analog output at the given lsn to the ending lsn"); +driver_return_code_t audio_play_lsn (CdIo_t *p_cdio, lsn_t start_lsn, + lsn_t end_lsn); +%inline %{ +driver_return_code_t audio_play_lsn (CdIo_t *p_cdio, lsn_t start_lsn, + lsn_t end_lsn) +{ + msf_t start_msf; + msf_t end_msf; + cdio_lsn_to_msf (start_lsn, &start_msf); + cdio_lsn_to_msf (end_lsn, &end_msf); + return cdio_audio_play_msf(p_cdio, &start_msf, &end_msf); +} +%} + +%rename cdio_audio_resume audio_resume; +%feature("autodoc", +"audio_resume(cdio)->status +Resume playing an audio CD."); +driver_return_code_t cdio_audio_resume (CdIo_t *p_cdio); + + +%rename cdio_audio_stop audio_stop; +%feature("autodoc", +"audio_stop(cdio)->status +Stop playing an audio CD."); +driver_return_code_t cdio_audio_stop (CdIo_t *p_cdio); + diff --git a/rbcdio/swig/compat.swg b/rbcdio/swig/compat.swg new file mode 100644 index 00000000..62a28ad7 --- /dev/null +++ b/rbcdio/swig/compat.swg @@ -0,0 +1,104 @@ +/* -*- c -*- + $Id: compat.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +%inline %{ +/* When libcdio version > 0.76 comes out this won't be needed. */ +#include +#if LIBCDIO_VERSION_NUM <= 76 + +/**< Masks derived from above... */ +#undef CDIO_DRIVE_CAP_WRITE_DVD +#define CDIO_DRIVE_CAP_WRITE_DVD ( \ + CDIO_DRIVE_CAP_WRITE_DVD_R \ + | CDIO_DRIVE_CAP_WRITE_DVD_PR \ + | CDIO_DRIVE_CAP_WRITE_DVD_RAM \ + | CDIO_DRIVE_CAP_WRITE_DVD_RW \ + | CDIO_DRIVE_CAP_WRITE_DVD_RPW \ + ) + +/** All the different ways a block/sector can be read. */ +typedef enum { + CDIO_READ_MODE_AUDIO, /**< CD-DA, audio, Red Book */ + CDIO_READ_MODE_M1F1, /**< Mode 1 Form 1 */ + CDIO_READ_MODE_M1F2, /**< Mode 1 Form 2 */ + CDIO_READ_MODE_M2F1, /**< Mode 2 Form 1 */ + CDIO_READ_MODE_M2F2, /**< Mode 2 Form 2 */ +} cdio_read_mode_t; + +/*! + Reads a number of sectors (AKA blocks). + + @param p_buf place to read data into. The caller should make sure + this location is large enough. See below for size information. + @param read_mode the kind of "mode" to use in reading. + @param i_lsn sector to read + @param i_blocks number of sectors to read + @return DRIVER_OP_SUCCESS (0) if no error, other (negative) enumerations + are returned on error. + + If read_mode is CDIO_MODE_AUDIO, + *p_buf should hold at least CDIO_FRAMESIZE_RAW * i_blocks bytes. + + If read_mode is CDIO_MODE_DATA, + *p_buf should hold at least i_blocks times either ISO_BLOCKSIZE, + M1RAW_SECTOR_SIZE or M2F2_SECTOR_SIZE depending on the kind of + sector getting read. If you don't know whether you have a Mode 1/2, + Form 1/ Form 2/Formless sector best to reserve space for the maximum + which is M2RAW_SECTOR_SIZE. + + If read_mode is CDIO_MODE_M2F1, + *p_buf should hold at least M2RAW_SECTOR_SIZE * i_blocks bytes. + + If read_mode is CDIO_MODE_M2F2, + *p_buf should hold at least CDIO_CD_FRAMESIZE * i_blocks bytes. + + +*/ +driver_return_code_t +cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + cdio_read_mode_t read_mode, uint32_t i_blocks) +{ + switch(read_mode) { + case CDIO_READ_MODE_AUDIO: + return cdio_read_audio_sectors (p_cdio, p_buf, i_lsn, i_blocks); + case CDIO_READ_MODE_M1F1: + return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, false, i_blocks); + case CDIO_READ_MODE_M1F2: + return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, true, i_blocks); + case CDIO_READ_MODE_M2F1: + return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, false, i_blocks); + case CDIO_READ_MODE_M2F2: + return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, true, i_blocks); + } + /* Can't happen. Just to shut up gcc. */ + return DRIVER_OP_ERROR; +} + +driver_return_code_t +cdio_eject_media_drive (const char *psz_drive) +{ + CdIo_t *p_cdio = cdio_open (psz_drive, DRIVER_DEVICE); + if (p_cdio) { + return cdio_eject_media(&p_cdio); + } else { + return DRIVER_OP_UNINIT; + } +} +#endif /* LIBCDIO_VERSION_NUM <= 76 */ +%} diff --git a/rbcdio/swig/device.swg b/rbcdio/swig/device.swg new file mode 100644 index 00000000..d7d77735 --- /dev/null +++ b/rbcdio/swig/device.swg @@ -0,0 +1,526 @@ +/* -*- c -*- + $Id: device.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. +*/ +/* See for more extensive documentation. */ + +%include "device_const.swg" + +/* Set up to allow functions returning device lists of type "char + **". We'll use a typedef so we can make sure to isolate this. I + don't think we need to in this program, but it I think it makes + thing clearer. +*/ +%inline %{ +typedef char ** DeviceList_t; +%} + +#ifdef DEVICELIST_FINISHED +%typemap(perl5,out) DeviceList_t { + // $1 is of type DeviceList_t + char **p = result; + unsigned int num = 0; + + if (!result) goto out; + + /* Figure out how many items in the array */ + for (p = $1; *p; p++) { + num++; + } + + /* For each element in the array of strings, create a new + * mortalscalar, and stuff it into the above array. */ + for (p = $1; *p; p++) { + /* Have perl compute the length of the string using strlen() */ + XPUSHs(sv_2mortal(newSVpv(*p, 0))); + } + argvi += num; + cdio_free_device_list($1); + out: ; +} +#endif + +%rename cdio_close_tray close_tray; +%feature("autodoc", +"close_tray(drive=nil, driver_id=nil) -> [status, driver_id] + +close media tray in CD drive if there is a routine to do so. +The driver id is returned. An exception is thrown on error."); +%apply int *INOUT { driver_id_t *p_driver_id }; +driver_return_code_t cdio_close_tray(const char *psz_drive=NULL, + driver_id_t *p_driver_id=NULL); + +%rename cdio_destroy close; +%feature("autodoc", +"destroy(p_cdio) +Free resources associated with p_cdio. Call this when done using +using CD reading/control operations for the current device. +"); +void cdio_destroy(CdIo_t *p_cdio); + +#if LIBCDIO_VERSION_NUM > 76 +/* cdio_driver_errmsg first appears in 0.77 code +*/ +%rename cdio_driver_errmsg driver_errmsg; +/*! + @param drc the return code you want interpreted. + @return the string information about drc +*/ +const char *cdio_driver_errmsg(driver_return_code_t drc); +#else +const char *driver_errmsg(driver_return_code_t drc); +%inline %{ +const char * +driver_errmsg(driver_return_code_t drc) +{ + switch(drc) { + case DRIVER_OP_SUCCESS: + return "driver operation was successful"; + case DRIVER_OP_ERROR: + return "driver I/O error"; + case DRIVER_OP_UNSUPPORTED: + return "driver operatation not supported"; + case DRIVER_OP_UNINIT: + return "driver not initialized"; + case DRIVER_OP_NOT_PERMITTED: + return "driver operatation not permitted"; + case DRIVER_OP_BAD_PARAMETER: + return "bad parameter passed"; + case DRIVER_OP_BAD_POINTER: + return "bad pointer to memory area"; + case DRIVER_OP_NO_DRIVER: + return "driver not available"; + default: + return "unknown or bad driver return status"; + } +} +%} +#endif /* LIBCDIO_VERSION_NUM > 76 */ +%feature("autodoc", +"eject_media(cdio)->return_code + +Eject media in CD drive if there is a routine to do so. +"); +driver_return_code_t eject_media (CdIo_t *p_cdio); +%inline %{ +driver_return_code_t +eject_media (CdIo_t *p_cdio) +{ + /* libcdio routines uses a Cdio_t **p_cdio, so we have to pass in + something it can clobber. + */ + CdIo_t **pp_cdio = &p_cdio; + return cdio_eject_media (pp_cdio); +} +%} + + +%rename cdio_eject_media_drive eject_media_drive; +%feature("autodoc", +"eject_media_drive(drive=nil)->return_code +Eject media in CD drive if there is a routine to do so. + +psz_drive: the name of the device to be acted upon. +The operation status is returned."); +driver_return_code_t cdio_eject_media_drive (const char *psz_drive=NULL); + +%rename cdio_get_arg get_arg; +%feature("autodoc", +"get_arg(p_cdio, key)->string + +Get the value associatied with key."); +const char *cdio_get_arg (const CdIo_t *p_cdio, const char key[]); + +%newobject cdio_get_default_device; // free malloc'd return value +%rename cdio_get_default_device get_device; +%feature("autodoc", +"get_device(cdio)->str + +Get the CD device associated with cdio. +If cdio is NULL (we haven't initialized a specific device driver), +then find a suitable one and return the default device for that. + +In some situations of drivers or OS's we can't find a CD device if +there is no media in it and it is possible for this routine to return +nil even though there may be a hardware CD-ROM."); +char *cdio_get_default_device (const CdIo_t *p_cdio=NULL); + +%newobject get_default_device_driver; // free malloc'd return value +%feature("autodoc", +"get_default_device_driver(driver_id=nil)->[device, driver] +Return a string containing the default CD device if none is specified. +if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE then find a suitable +one set the default device for that. + +nil is returned as the device if we couldn't get a default device."); +%apply driver_id_t *OUTPUT { driver_id_t *p_out_driver_id }; +char *get_default_device_driver (driver_id_t p_driver_id, + driver_id_t *p_out_driver_id); +%inline %{ +char * +get_default_device_driver(driver_id_t driver_id, driver_id_t *p_out_driver_id) +{ + *p_out_driver_id = driver_id; + return cdio_get_default_device_driver(p_out_driver_id); +} +%} + +#ifdef DEVICELIST_FINISHED +%rename cdio_get_devices get_devices; +/*! Return an array of device names. If you want a specific + devices for a driver, give that device. If you want hardware + devices, give DRIVER_DEVICE and if you want all possible devices, + image drivers and hardware drivers give DRIVER_UNKNOWN. + + NULL is returned if we couldn't return a list of devices. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it and it is possible for this routine to return + NULL even though there may be a hardware CD-ROM. +*/ +DeviceList_t cdio_get_devices (driver_id_t driver_id); + +/* Like cdio_get_devices, but we may change the p_driver_id if we + were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because + often one wants to get a drive name and then *open* it + afterwards. Giving the driver back facilitates this, and speeds + things up for libcdio as well. +*/ + +DeviceList_t get_devices_ret (driver_id_t driver_id, + driver_id_t *p_out_driver_id); +%inline %{ +DeviceList_t get_devices_ret (driver_id_t driver_id, + driver_id_t *p_out_driver_id) { + *p_out_driver_id = driver_id; + return cdio_get_devices_ret (p_out_driver_id); + } +%} + +%feature("autodoc", +"get_devices_with_cap(capabilities, any)->[device1, device2...] +Get an array of device names in search_devices that have at least +the capabilities listed by the capabities parameter. + +If any is False then every capability listed in the +extended portion of capabilities (i.e. not the basic filesystem) +must be satisified. If any is True, then if any of the +capabilities matches, we call that a success. + +To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL. + +The array of device names is returned or NULL if we couldn't get a +default device. It is also possible to return a non NULL but after +dereferencing the the value is NULL. This also means nothing was +found."); +DeviceList_t get_devices_with_cap (unsigned int capabilities, bool b_any); +%inline %{ +DeviceList_t +get_devices_with_cap (unsigned int capabilities, bool b_any) { + /* FIXME: ? libcdio allows one to specify a list (char **) of devices + to search. Don't know how to do that via SWIG though. */ + return cdio_get_devices_with_cap (NULL, (cdio_fs_anal_t) capabilities, + b_any); + } +%} +#endif /* DEVICELIST_FINISHED */ + +%apply driver_id_t *OUTPUT { driver_id_t *p_out_driver_id }; +%newobject get_devices_with_cap_ret; +%feature("autodoc", +"Like cdio_get_devices_with_cap but we return the driver we found +as well. This is because often one wants to search for kind of drive +and then *open* it afterwards. Giving the driver back facilitates this, + and speeds things up for libcdio as well."); +DeviceList_t get_devices_with_cap_ret (unsigned int capabilities, bool b_any, + driver_id_t *p_out_driver_id); +#ifdef DEVICELIST_FINISHED +%inline %{ +DeviceList_t +get_devices_with_cap_ret (unsigned int capabilities, bool b_any, + driver_id_t *p_out_driver_id) { + /* FIXME: ? libcdio allows one to specify a list (char **) of devices + to search. Don't know how to do that via SWIG though. */ + return cdio_get_devices_with_cap_ret (NULL, + (cdio_fs_anal_t) capabilities, b_any, + p_out_driver_id); + } +%} +#endif /* DEVICELIST_FINISHED */ + +%rename cdio_get_drive_cap get_drive_cap; +%feature("autodoc", +"get_drive_cap()->(read_cap, write_cap, misc_cap) + +Get drive capabilities of device. + +In some situations of drivers or OS's we can't find a CD device if +there is no media in it. In this situation capabilities will show up as +empty even though there is a hardware CD-ROM."); +%apply uint32_t *OUTPUT { uint32_t *p_read_cap, + uint32_t *p_write_cap, + uint32_t *p_misc_cap }; +void cdio_get_drive_cap (const CdIo_t *p_cdio, + uint32_t *p_read_cap, + uint32_t *p_write_cap, + uint32_t *p_misc_cap); + +%rename cdio_get_drive_cap_dev get_drive_cap; +%feature("autodoc", +"get_drive_cap_dev()->(read_cap, write_cap, misc_cap) + +Get drive capabilities of device. + +In some situations of drivers or OS's we can't find a CD device if +there is no media in it. In this situation capabilities will show up as +empty even though there is a hardware CD-ROM."); + +void cdio_get_drive_cap_dev(const char *device=NULL, + uint32_t *p_read_cap, + uint32_t *p_write_cap, + uint32_t *p_misc_cap); + +%rename cdio_get_driver_name get_driver_name; +%feature("autodoc", +"get_driver_name(cdio)-> string + +return a string containing the name of the driver in use. +"); +const char *cdio_get_driver_name (const CdIo_t *p_cdio); + +%rename cdio_get_driver_id get_driver_id; +%feature("autodoc", +"get_driver_id(cdio)-> int + +Return the driver id of the driver in use. +if cdio has not been initialized or is nil, +return pycdio.DRIVER_UNKNOWN."); +driver_id_t cdio_get_driver_id (const CdIo_t *p_cdio); + +%rename cdio_get_last_session get_last_session; +%apply int32_t *OUTPUT { lsn_t *i_last_session }; +driver_return_code_t cdio_get_last_session (CdIo_t *p_cdio, + lsn_t *i_last_session); + +%feature("autodoc", +"have_driver(driver_id) -> int + +Return 1 if we have driver driver_id, 0 if not and -1 +if driver id is out of range."); +%inline %{ +int +have_driver (unsigned int driver_id) +{ + if (driver_id < CDIO_MIN_DRIVER || driver_id > CDIO_MAX_DRIVER) + return -1; + if (cdio_have_driver(driver_id)) return 1; + return 0; +} +%} + +%feature("autodoc", +"have_ATAPI(CdIo_t *p_cdio)->bool +return True if CD-ROM understand ATAPI commands."); +%inline %{ +/*! True if CD-ROM understand ATAPI commands. */ +bool +have_ATAPI (CdIo_t *p_cdio) +{ + return cdio_have_atapi(p_cdio) == yep; +} +%} + +%newobject cdio_is_binfile; // free malloc'd return value +%rename cdio_is_binfile is_binfile; +%feature("autodoc", +"is_binfile(binfile_name)->cue_name + +Determine if binfile_name is the BIN file part of a CDRWIN CD disk +image. + +Return the corresponding CUE file if bin_name is a BIN file or +nil if not a BIN file."); +char *cdio_is_binfile(const char *bin_name); + +%newobject cdio_is_cuefile; // free malloc'd return value +%rename cdio_is_cuefile is_cuefile; +%feature("autodoc", +"is_cuefile(cuefile_name)->bin_name + +Determine if cuefile_name is the CUE file part of a CDRWIN CD disk +image. + +Return the corresponding BIN file if bin_name is a CUE file or +nil if not a CUE file."); +char *cdio_is_cuefile(const char *cue_name); + +#if LIBCDIO_VERSION_NUM <= 76 +/* There is a bug in the 0.76 code when driver_id==DRIVER_UNKNOWN + or DRIVER_DEVICE, so here we'll use code from compat.swg. +*/ +bool is_device(const char *psz_source, + driver_id_t driver_id=DRIVER_UNKNOWN); + +%inline %{ +bool +is_device(const char *psz_source, driver_id_t driver_id) +{ + if (DRIVER_UNKNOWN == driver_id || DRIVER_DEVICE == driver_id) { + char *psz_drive = cdio_get_default_device_driver(&driver_id); + /* We don't need the psz_drive, just the driver_id */ + free(psz_drive); + } + return cdio_is_device(psz_source, driver_id); +} +%} +#else +%rename cdio_is_device is_device; +bool cdio_is_device(const char *psz_source, + driver_id_t driver_id=DRIVER_UNKNOWN); +#endif /* LIBCDIO_VERSION_NUM <= 76 */ + +%rename cdio_is_nrg is_nrg; +%feature("autodoc", +"is_nrg(cue_name)->bool + +Determine if nrg_name is a Nero CD disc image"); +bool cdio_is_nrg(const char *nrg_name); + +%rename cdio_is_tocfile is_tocfile; +%feature("autodoc", +"is_tocfile(tocfile_name)->bool + +Determine if tocfile_name is a cdrdao CD disc image"); +bool cdio_is_tocfile(const char *tocfile_name); + +%rename cdio_get_media_changed get_media_changed; +%feature("autodoc", +"get_media_changed(cdio) -> int + +Find out if media has changed since the last call. +Return 1 if media has changed since last call, 0 if not. Error +return codes are the same as driver_return_code_t"); +int cdio_get_media_changed(CdIo_t *p_cdio); + +/* Set up to allow returning hardware info. We'll use a typedef so we + can make sure to isolate this. +*/ +%inline %{ +typedef char ** HWInfo_t; +%} + +%typemap(perl5,out) HWInfo_t { // All functions returning char ** + // get this typemap + // $1 is of type char ** + char **p = $1; + unsigned int num = 0; + + /* Figure out how many items in the array */ + for (p = $1; *p; p++) { + num++; + } + + if (argvi >= items) { + /* Extend the stack by num objects */ + EXTEND(sp, num); + } + /* For each element in the array of strings, create a new + * mortalscalar, and stuff it into the above array. */ + for (p = $1; *p; p++) { + /* Have perl compute the length of the string using strlen() */ + PUSHs(sv_2mortal(newSVpv(*p, 0))); + } + /* FIXME: the + 1 is because p_cdio is still on the stack. */ + argvi += num + 1; +} + +/* +get_hwinfo(p_cdio)->[vendor, model, release] +Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. +An exception is raised if we had an error. +*/ +%apply int *OUTPUT { int *drc }; +const HWInfo_t get_hwinfo ( const CdIo_t *p_cdio, int *drc); + +%inline %{ +static cdio_hwinfo_t hw_info; +const +HWInfo_t get_hwinfo ( const CdIo_t *p_cdio, int *drc) +{ + static const char *hwinfo[4] = { + hw_info.psz_vendor, + hw_info.psz_model, + hw_info.psz_revision, + NULL + }; + bool b_got_hwinfo = cdio_get_hwinfo(p_cdio, &hw_info); + + *drc = b_got_hwinfo; + return (const HWInfo_t) hwinfo; +} +%} + +%rename cdio_set_blocksize set_blocksize; +%feature("autodoc", +"set_blocksize(cdio, blocksize)->return_status + +Set the blocksize for subsequent reads."); +driver_return_code_t cdio_set_blocksize ( const CdIo_t *p_cdio, + int i_blocksize ); + +%rename cdio_set_speed set_speed; +%feature("autodoc", +"cdio_set_speed(cdio, speed)->return_status +Set the drive speed."); +driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio, int i_speed ); + + +/**** Using the name open() conflicts with some C routine. + So we use open_cd() instead. +***/ +%feature("autodoc", +"open_cd(source=NULL, driver_id=nil, access_mode=nil) + +Sets up to read from place specified by source, driver_id and +access mode. This should be called before using any other routine +except those that act on a CD-ROM drive by name. + +If nil is given as the source, we'll use the default driver device. +If nil is given as the driver_id, we'll find a suitable device driver. + +Return the a pointer than can be used in subsequent operations or +nil on error or no device."); +CdIo_t *open_cd(const char *psz_source, + driver_id_t driver_id=DRIVER_UNKNOWN, + const char *psz_access_mode=NULL); + +%inline %{ + CdIo_t *open_cd(const char *psz_orig_source, driver_id_t driver_id, + const char *psz_orig_access_mode) +{ + char *psz_source = psz_orig_source; + char *psz_access_mode = psz_orig_access_mode; + + if (psz_source || strlen(psz_source) == 0) + psz_source = NULL; + if (psz_access_mode || strlen(psz_access_mode) == 0) + psz_access_mode = NULL; + return cdio_open_am(psz_source, driver_id, psz_access_mode); +} +%} diff --git a/rbcdio/swig/device_const.swg b/rbcdio/swig/device_const.swg new file mode 100644 index 00000000..f4494110 --- /dev/null +++ b/rbcdio/swig/device_const.swg @@ -0,0 +1,144 @@ +/* -*- c -*- + $Id: device_const.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* See for more extensive documentation. */ + +/**** ALL OF THESE ARE CONSTANTS *** */ +%immutable; + +/* Drive types returned by cdio_get_drive_cap() */ +%constant long int DRIVE_CAP_ERROR = CDIO_DRIVE_CAP_ERROR; +%constant long int DRIVE_CAP_UNKNOWN = CDIO_DRIVE_CAP_UNKNOWN; +%constant long int DRIVE_CAP_MISC_CLOSE_TRAY = CDIO_DRIVE_CAP_MISC_CLOSE_TRAY; +%constant long int DRIVE_CAP_MISC_EJECT = CDIO_DRIVE_CAP_MISC_EJECT; +%constant long int DRIVE_CAP_MISC_LOCK = CDIO_DRIVE_CAP_MISC_LOCK ; +%constant long int DRIVE_CAP_MISC_SELECT_SPEED = CDIO_DRIVE_CAP_MISC_SELECT_SPEED; +%constant long int DRIVE_CAP_MISC_SELECT_DISC = CDIO_DRIVE_CAP_MISC_SELECT_DISC; +%constant long int DRIVE_CAP_MISC_MULTI_SESSION = CDIO_DRIVE_CAP_MISC_MULTI_SESSION; +%constant long int DRIVE_CAP_MISC_MEDIA_CHANGED = CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED; +%constant long int DRIVE_CAP_MISC_RESET = CDIO_DRIVE_CAP_MISC_RESET; +%constant long int DRIVE_CAP_MISC_FILE = CDIO_DRIVE_CAP_MISC_FILE; + +/* Reading masks.. */ +%constant long int DRIVE_CAP_READ_AUDIO = CDIO_DRIVE_CAP_READ_AUDIO; +%constant long int DRIVE_CAP_READ_CD_DA = CDIO_DRIVE_CAP_READ_CD_DA; +%constant long int DRIVE_CAP_READ_CD_G = CDIO_DRIVE_CAP_READ_CD_G; +%constant long int DRIVE_CAP_READ_CD_R = CDIO_DRIVE_CAP_READ_CD_R; +%constant long int DRIVE_CAP_READ_CD_RW = CDIO_DRIVE_CAP_READ_CD_RW; +%constant long int DRIVE_CAP_READ_DVD_R = CDIO_DRIVE_CAP_READ_DVD_R; +%constant long int DRIVE_CAP_READ_DVD_PR = CDIO_DRIVE_CAP_READ_DVD_PR; +%constant long int DRIVE_CAP_READ_DVD_RAM = CDIO_DRIVE_CAP_READ_DVD_RAM; +%constant long int DRIVE_CAP_READ_DVD_ROM = CDIO_DRIVE_CAP_READ_DVD_ROM; +%constant long int DRIVE_CAP_READ_DVD_RW = CDIO_DRIVE_CAP_READ_DVD_RW; +%constant long int DRIVE_CAP_READ_DVD_RPW = CDIO_DRIVE_CAP_READ_DVD_RPW; +%constant long int DRIVE_CAP_READ_C2_ERRS = CDIO_DRIVE_CAP_READ_C2_ERRS; +%constant long int DRIVE_CAP_READ_MODE2_FORM1 = CDIO_DRIVE_CAP_READ_MODE2_FORM1; +%constant long int DRIVE_CAP_READ_MODE2_FORM2 = CDIO_DRIVE_CAP_READ_MODE2_FORM2; +%constant long int DRIVE_CAP_READ_MCN = CDIO_DRIVE_CAP_READ_MCN; +%constant long int DRIVE_CAP_READ_ISRC = CDIO_DRIVE_CAP_READ_ISRC; + +/* Writing masks.. */ +%constant long int DRIVE_CAP_WRITE_CD_R = CDIO_DRIVE_CAP_WRITE_CD_R; +%constant long int DRIVE_CAP_WRITE_CD_RW = CDIO_DRIVE_CAP_WRITE_CD_RW; +%constant long int DRIVE_CAP_WRITE_DVD_R = CDIO_DRIVE_CAP_WRITE_DVD_R; +%constant long int DRIVE_CAP_WRITE_DVD_PR = CDIO_DRIVE_CAP_WRITE_DVD_PR; +%constant long int DRIVE_CAP_WRITE_DVD_RAM = CDIO_DRIVE_CAP_WRITE_DVD_RAM; +%constant long int DRIVE_CAP_WRITE_DVD_RW = CDIO_DRIVE_CAP_WRITE_DVD_RW ; +%constant long int DRIVE_CAP_WRITE_DVD_RPW = CDIO_DRIVE_CAP_WRITE_DVD_RPW; +%constant long int DRIVE_CAP_WRITE_MT_RAINIER = CDIO_DRIVE_CAP_WRITE_MT_RAINIER; +%constant long int DRIVE_CAP_WRITE_BURN_PROOF = CDIO_DRIVE_CAP_WRITE_BURN_PROOF; + +/*** Masks derived from above... ***/ +/* Has some sort of CD writer ability. */ +%constant long int DRIVE_CAP_WRITE_CD = CDIO_DRIVE_CAP_WRITE_CD; +/* Has some sort of DVD writer ability */ +%constant long int DRIVE_CAP_WRITE_DVD = CDIO_DRIVE_CAP_WRITE_DVD; +%constant long int DRIVE_CAP_WRITE = CDIO_DRIVE_CAP_WRITE; + +/*! Size of fields returned by an INQUIRY command */ +%constant long int MMC_HW_VENDOR_LEN = CDIO_MMC_HW_VENDOR_LEN; +%constant long int MMC_HW_MODEL_LEN = CDIO_MMC_HW_MODEL_LEN; +%constant long int MMC_HW_REVISION_LEN = CDIO_MMC_HW_REVISION_LEN; + +/**! Flags specifying the category of device to open or is opened. */ +%constant long int SRC_IS_DISK_IMAGE_MASK = CDIO_SRC_IS_DISK_IMAGE_MASK; +%constant long int SRC_IS_DEVICE_MASK = CDIO_SRC_IS_DEVICE_MASK; +%constant long int SRC_IS_SCSI_MASK = CDIO_SRC_IS_SCSI_MASK; +%constant long int SRC_IS_NATIVE_MASK = CDIO_SRC_IS_NATIVE_MASK; + +/* driver_id_t enums. */ +%constant long int DRIVER_UNKNOWN = DRIVER_UNKNOWN; +%constant long int DRIVER_AIX = DRIVER_AIX; +%constant long int DRIVER_BSDI = DRIVER_BSDI; +%constant long int DRIVER_FREEBSD = DRIVER_FREEBSD; +%constant long int DRIVER_LINUX = DRIVER_LINUX; +%constant long int DRIVER_SOLARIS = DRIVER_SOLARIS; +%constant long int DRIVER_OSX = DRIVER_OSX; +%constant long int DRIVER_WIN32 = DRIVER_WIN32; +%constant long int DRIVER_CDRDAO = DRIVER_CDRDAO; +%constant long int DRIVER_BINCUE = DRIVER_BINCUE; +%constant long int DRIVER_NRG = DRIVER_NRG; +%constant long int DRIVER_DEVICE = DRIVER_DEVICE; + +%constant long int MIN_DRIVER = CDIO_MIN_DRIVER; +%constant long int MIN_DEVICE_DRIVER = CDIO_MIN_DEVICE_DRIVER; +%constant long int MAX_DRIVER = CDIO_MAX_DRIVER; +%constant long int MAX_DEVICE_DRIVER = CDIO_MAX_DEVICE_DRIVER; + + +%constant long int DRIVER_OP_SUCCESS = DRIVER_OP_SUCCESS; +%constant long int DRIVER_OP_ERROR = DRIVER_OP_ERROR; +%constant long int DRIVER_OP_UNSUPPORTED = DRIVER_OP_UNSUPPORTED; +%constant long int DRIVER_OP_UNINIT = DRIVER_OP_UNINIT; +%constant long int DRIVER_OP_NOT_PERMITTED = DRIVER_OP_NOT_PERMITTED; +%constant long int DRIVER_OP_BAD_PARAMETER = DRIVER_OP_BAD_PARAMETER; +%constant long int DRIVER_OP_BAD_POINTER = DRIVER_OP_BAD_POINTER; +%constant long int DRIVER_OP_NO_DRIVER = DRIVER_OP_NO_DRIVER; + +%constant unsigned int FS_AUDIO = CDIO_FS_AUDIO; +%constant unsigned int FS_HIGH_SIERRA = CDIO_FS_HIGH_SIERRA; +%constant unsigned int FS_ISO_9660 = CDIO_FS_ISO_9660; +%constant unsigned int FS_INTERACTIVE = CDIO_FS_INTERACTIVE; +%constant unsigned int FS_HFS = CDIO_FS_HFS; +%constant unsigned int FS_UFS = CDIO_FS_UFS; +%constant unsigned int FS_EXT2 = CDIO_FS_EXT2; +%constant unsigned int FS_ISO_HFS = CDIO_FS_ISO_HFS; +%constant unsigned int FS_ISO_9660_INTERACTIVE = CDIO_FS_ISO_9660_INTERACTIVE; +%constant unsigned int FS_3DO = CDIO_FS_3DO; +%constant unsigned int FS_XISO = CDIO_FS_XISO; +%constant unsigned int FS_UDFX = CDIO_FS_UDFX; +%constant unsigned int FS_UDF = CDIO_FS_UDF; +%constant unsigned int FS_ISO_UDF = CDIO_FS_ISO_UDF; + +%constant unsigned int FS_ANAL_XA = CDIO_FS_ANAL_XA; +%constant unsigned int FS_ANAL_MULTISESSION = CDIO_FS_ANAL_MULTISESSION; +%constant unsigned int FS_ANAL_PHOTO_CD = CDIO_FS_ANAL_PHOTO_CD; +%constant unsigned int FS_ANAL_HIDDEN_TRACK = CDIO_FS_ANAL_HIDDEN_TRACK; +%constant unsigned int FS_ANAL_CDTV = CDIO_FS_ANAL_CDTV; +%constant unsigned int FS_ANAL_BOOTABLE = CDIO_FS_ANAL_BOOTABLE; +%constant unsigned int FS_ANAL_VIDEOCD = CDIO_FS_ANAL_VIDEOCD; +%constant unsigned int FS_ANAL_ROCKRIDGE = CDIO_FS_ANAL_ROCKRIDGE; +%constant unsigned int FS_ANAL_JOLIET = CDIO_FS_ANAL_JOLIET; +%constant unsigned int FS_ANAL_SVCD = CDIO_FS_ANAL_SVCD; +%constant unsigned int FS_ANAL_CVD = CDIO_FS_ANAL_CVD; +%constant unsigned int FS_ANAL_XISO = CDIO_FS_ANAL_XISO; +%constant unsigned int FS_MATCH_ALL = CDIO_FS_MATCH_ALL; +%constant unsigned int FS_UNKNOWN = CDIO_FS_UNKNOWN; + +%mutable; diff --git a/rbcdio/swig/disc.swg b/rbcdio/swig/disc.swg new file mode 100644 index 00000000..b415ce36 --- /dev/null +++ b/rbcdio/swig/disc.swg @@ -0,0 +1,96 @@ +/* -*- c -*- + $Id: disc.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* See for more extensive documentation. */ + +%constant long int DISC_MODE_CD_DA = CDIO_DISC_MODE_CD_DA; +%constant long int DISC_MODE_CD_DATA = CDIO_DISC_MODE_CD_DATA; +%constant long int DISC_MODE_CD_XA = CDIO_DISC_MODE_CD_XA; +%constant long int DISC_MODE_CD_MIXED = CDIO_DISC_MODE_CD_MIXED; +%constant long int DISC_MODE_DVD_ROM = CDIO_DISC_MODE_DVD_ROM; +%constant long int DISC_MODE_DVD_RAM = CDIO_DISC_MODE_DVD_RAM; +%constant long int DISC_MODE_DVD_R = CDIO_DISC_MODE_DVD_R; +%constant long int DISC_MODE_DVD_RW = CDIO_DISC_MODE_DVD_RW; +%constant long int DISC_MODE_DVD_PR = CDIO_DISC_MODE_DVD_PR; +%constant long int DISC_MODE_DVD_PRW = CDIO_DISC_MODE_DVD_PRW; +%constant long int DISC_MODE_DVD_OTHER = CDIO_DISC_MODE_DVD_OTHER; +%constant long int DISC_MODE_NO_INFO = CDIO_DISC_MODE_NO_INFO; +%constant long int DISC_MODE_ERROR = CDIO_DISC_MODE_ERROR; +%constant long int DISC_MODE_CD_I = CDIO_DISC_MODE_CD_I; + +%rename cdio_get_disc_last_lsn get_disc_last_lsn; +%feature("autodoc", +"get_disc_last_lsn(cdio)->lsn +Get the LSN of the end of the CD. + +perlcdio.INVALID_LSN is returned on error."); +lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio); + + +%feature("autodoc", +"get_disc_mode(p_cdio) -> str + +Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc. +that we've got. The notion of 'CD' is extended a little to include +DVD's."); +const char *get_disc_mode (CdIo_t *p_cdio); + +%rename cdio_get_joliet_level get_joliet_level; +%feature("autodoc", +"get_joliet_level(cdio)->int + +Return the Joliet level recognized for cdio. +This only makes sense for something that has an ISO-9660 +filesystem."); +int cdio_get_joliet_level(const CdIo_t *p_cdio); + +/*! + Get the media catalog number (MCN) from the CD. + + @return the media catalog number or NULL if there is none or we + don't have the ability to get it. + + Note: string is malloc'd so caller has to free() the returned + string when done with it. + +*/ +%rename cdio_get_mcn get_mcn; +%newobject cdio_get_mcn; // free malloc'd return value +char * cdio_get_mcn (const CdIo_t *p_cdio); + +%rename cdio_get_num_tracks get_num_tracks; +%feature("autodoc", +"get_num_tracks(p_cdio)->int + +Return the number of tracks on the CD. +On error rubycdio::INVALID_TRACK is returned."); +track_t cdio_get_num_tracks (const CdIo_t *p_cdio); + +/*========================INLINE======================================*/ + +%inline %{ +const char * +get_disc_mode (CdIo_t *p_cdio) +{ + discmode_t discmode = cdio_get_discmode(p_cdio); + if (CDIO_DISC_MODE_ERROR == discmode) return NULL; + return discmode2str[discmode]; +} + +%} diff --git a/rbcdio/swig/rubycdio.swg b/rbcdio/swig/rubycdio.swg new file mode 100644 index 00000000..691f6a0e --- /dev/null +++ b/rbcdio/swig/rubycdio.swg @@ -0,0 +1,89 @@ +/* -*- c -*- + $Id: rubycdio.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. +*/ +%define DOCSTRING +"This is a wrapper for The CD Input and Control library (libcdio) which +encapsulates CD-ROM reading and control. Python programs wishing to be +oblivious of the OS- and device-dependent properties of a CD-ROM can +use this library." +%enddef +%module(docstring=DOCSTRING) rubycdio +%{ +/* Includes the header in the wrapper code */ +#include +#include +#include +%} + +#include +#include + +%include "compat.swg" + +%include "typemaps.i" + +/* Various libcdio constants and typedefs */ +%include "types.swg" + +%feature("autodoc", 1); + +%include "audio.swg" + +#if FINISHED +%include "read.swg" +#endif +%include "track.swg" + +/* In the presence of the exception handling, the order is important. + The below use %exception. +*/ +%include "device.swg" +%include "disc.swg" + +/* Encapsulation is done in two parts. The lower-level python +interface is called rubycdio and is generated by SWIG. + +The more object-oriented module is cdio; it is a Python class that +uses rubycdio. Although rubycdio is perfectly usable on its own, it is +expected that cdio is what most people will use. As rubycdio more +closely models the C interface, it is conceivable (if unlikely) that +diehard libcdio C users who are very familiar with that interface +could prefer that. + +It is probably possible to change the SWIG in such a way to combine +these pieces. However there are the problems. First, I'm not that much +of a SWIG expert. Second it looks as though the resulting SWIG code +would be more complex. Third the separation makes translation very +straight forward to understand and maintain: first get what's in C +into Python as a one-to-one translation. Then we implement some nice +abstraction off of that. The abstraction can be modified without +having to redo the underlying translation. (But the reverse is +generally not true: usually changes to the C-to-python translation, +rubycdio, do result in small, but obvious and straightforward changes to +the abstraction layer cdio.) + */ +#define INCLUDE_CLASS 0 +#if INCLUDE_CLASS +/* In spite of the above, if we were to do things as a one-step approach, + this might be how it would be done. */ +%rubycode %{ +%include "cdio.rb" +%} +#endif diff --git a/rbcdio/swig/track.swg b/rbcdio/swig/track.swg new file mode 100644 index 00000000..44d382a0 --- /dev/null +++ b/rbcdio/swig/track.swg @@ -0,0 +1,207 @@ +/* -*- c -*- + $Id: track.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston=, MA 02111-1307 USA +*/ + +/* See For more extensive documentation */ +%constant long int TRACK_FORMAT_AUDIO = TRACK_FORMAT_AUDIO; +%constant long int TRACK_FORMAT_CDI = TRACK_FORMAT_CDI; +%constant long int TRACK_FORMAT_XA = TRACK_FORMAT_XA; +%constant long int TRACK_FORMAT_DATA = TRACK_FORMAT_DATA; +%constant long int TRACK_FORMAT_PSX = TRACK_FORMAT_PSX; + +%constant long int CDIO_TRACK_FLAG_FALSE = CDIO_TRACK_FLAG_FALSE; +%constant long int CDIO_TRACK_FLAG_TRUE = CDIO_TRACK_FLAG_TRUE; +%constant long int CDIO_TRACK_FLAG_ERROR = CDIO_TRACK_FLAG_ERROR; +%constant long int CDIO_TRACK_FLAG_UNKNOWN = CDIO_TRACK_FLAG_UNKNOWN; + +%constant long int CDIO_CDROM_LBA = CDIO_CDROM_LBA; +%constant long int CDIO_CDROM_MSF = CDIO_CDROM_MSF; +%constant long int CDIO_CDROM_DATA_TRACK = CDIO_CDROM_DATA_TRACK; +%constant long int CDIO_CDROM_CDI_TRACK = CDIO_CDROM_CDI_TRACK; +%constant long int CDIO_CDROM_XA_TRACK = CDIO_CDROM_XA_TRACK; + +%constant long int AUDIO = AUDIO; +%constant long int MODE1 = MODE1; +%constant long int MODE1_RAW = MODE1_RAW; +%constant long int MODE2 = MODE2; +%constant long int MODE2_FORM1 = MODE2_FORM1; +%constant long int MODE2_FORM2 = MODE2_FORM2; +%constant long int MODE2_FORM_MIX = MODE2_FORM_MIX; +%constant long int MODE2_RAW = MODE2_RAW; + +%constant long int INVALID_TRACK = CDIO_INVALID_TRACK; +%constant long int CDROM_LEADOUT_TRACK = 0xAA; + +typedef int track_flag_t; + +%rename cdio_get_first_track_num get_first_track_num; +%feature("autodoc", +"get_first_track_num(p_cdio) -> int +Get the number of the first track. + +return the track number or pycdio.INVALID_TRACK if there was +a problem."); +track_t cdio_get_first_track_num(const CdIo_t *p_cdio); + +%rename cdio_get_last_track_num get_last_track_num ; +%feature("autodoc", +"get_last_track_num +Return the last track number. +pycdio.INVALID_TRACK is if there was a problem."); +track_t cdio_get_last_track_num (const CdIo_t *p_cdio); + +%rename cdio_get_track get_track; +%feature("autodoc", +"cdio_get_track(lsn)->int + + Find the track which contains lsn. + pycdio.INVALID_TRACK is returned if the lsn outside of the CD or + if there was some error. + + If the lsn is before the pregap of the first track, 0 is returned. + Otherwise we return the track that spans the lsn."); +track_t cdio_get_track(const CdIo_t *p_cdio, lsn_t lsn); + +%rename cdio_get_track_channels get_track_channels; +%feature("autodoc", +"get_track_channels(cdio, track)->int + +Return number of channels in track: 2 or 4; -2 if implemented or -1 +for error. Not meaningful if track is not an audio track."); +int cdio_get_track_channels(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_copy_permit get_track_copy_permit; +%feature("autodoc", +"get_copy_permit(cdio, track)->int + +Return copy protection status on a track. Is this meaningful +not an audio track? +"); +track_flag_t cdio_get_track_copy_permit(const CdIo_t *p_cdio, + track_t i_track); + +%feature("autodoc", +"get_track_format(cdio, track)->format + +Get the format (audio, mode2, mode1) of track. "); +const char *get_track_format(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_green is_track_green; +%feature("autodoc", +"is_track_green(cdio, track) -> bool + +Return True if we have XA data (green, mode2 form1) or +XA data (green, mode2 form2). That is track begins: + sync - header - subheader +12 4 - 8 + +FIXME: there's gotta be a better design for this and get_track_format?"); +bool cdio_get_track_green(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_last_lsn get_track_last_lsn; +%feature("autodoc", +"cdio_get_track_last_lsn(cdio, track)->lsn + +Return the ending LSN for track number +track in cdio. CDIO_INVALID_LSN is returned on error."); +lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_lba get_track_lba; +%feature("autodoc", +"cdio_get_track_lba + Get the starting LBA for track number + i_track in p_cdio. Track numbers usually start at something + greater than 0, usually 1. + + The 'leadout' track is specified either by + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. + + @param p_cdio object to get information from + @param i_track the track number we want the LSN for + @return the starting LBA or CDIO_INVALID_LBA on error."); + lba_t cdio_get_track_lba(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_lsn get_track_lsn; +%feature("autodoc", +"cdio_get_track_lsn (cdio, track)->int + +Return the starting LSN for track number. +Track numbers usually start at something greater than 0, usually 1. + +The 'leadout' track is specified either by +using i_track pycdio.CDROM_LEADOUT_TRACK or the total tracks+1. + +pycdio.INVALID_LSN is returned on error."); +lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track); + +%feature("autodoc", +"get_track_msf(cdio,track)->string + + Return the starting MSF (minutes/secs/frames) for track number + track. Track numbers usually start at something + greater than 0, usually 1. + + The 'leadout' track is specified either by + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. + +@return string mm:ss:ff if all good, or string 'error' on error."); +char *get_track_msf(const CdIo_t *p_cdio, track_t i_track); +%inline %{ +char *get_track_msf(const CdIo_t *p_cdio, track_t i_track) +{ + msf_t msf; + + if (!cdio_get_track_msf( p_cdio, i_track, &msf )) { + return NULL; + } else { + return cdio_msf_to_str( &msf ); + } +} +%} + +%rename cdio_get_track_preemphasis get_track_preemphasis; +%feature("autodoc", +"cdio_get_track_preemphasis(cdio, track) + +Get linear preemphasis status on an audio track. +This is not meaningful if not an audio track?"); +track_flag_t cdio_get_track_preemphasis(const CdIo_t *p_cdio, track_t i_track); + +%rename cdio_get_track_sec_count get_track_sec_count; +%feature("autodoc", +"get_track_sec_count(cdio, track)->int + +Get the number of sectors between this track an the next. This +includes any pregap sectors before the start of the next track. +Track numbers usually start at something +greater than 0, usually 1. + +0 is returned if there is an error."); +unsigned int cdio_get_track_sec_count(const CdIo_t *p_cdio, track_t i_track); + +%inline %{ +const char +*get_track_format(const CdIo_t *p_cdio, track_t i_track) +{ + track_format_t track_format = cdio_get_track_format(p_cdio, i_track); + return track_format2str[track_format]; +} +%} + + diff --git a/rbcdio/swig/types.swg b/rbcdio/swig/types.swg new file mode 100644 index 00000000..f3d851be --- /dev/null +++ b/rbcdio/swig/types.swg @@ -0,0 +1,62 @@ +/* -*- c -*- + $Id: types.swg,v 1.1 2006/11/13 05:12:42 rocky Exp $ + + Copyright (C) 2006 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + Various typedef's "constant"s/variables + + Many of these are documented more fully in libcdio's + I'm not sure why, but including that directly will not allow + SWIG to understand say that a lsn_t is an int. +*/ + +#ifdef NEED_LONG +#define LONG long +#else +#define LONG +#endif + +#define uint32_t LONG unsigned int +#define uint16_t LONG unsigned int +#define int32_t LONG int +#define uint8_t unsigned char + +typedef long int my_ssize_t; +typedef unsigned int driver_id_t; +typedef int lsn_t; +typedef int int16_t; +typedef int lba_t; +typedef unsigned int track_t; +typedef long int driver_return_code_t; +typedef long int ssize_t; +typedef unsigned int cdio_drive_read_cap_t; +typedef unsigned int cdio_drive_write_cap_t; +typedef unsigned int cdio_drive_misc_cap_t; + +%constant long int VERSION_NUM = LIBCDIO_VERSION_NUM; + +%constant long int INVALID_LBA = CDIO_INVALID_LBA; +%constant long int INVALID_LSN = CDIO_INVALID_LSN; + +/* More documentation on the below is in cdio/sector.h */ +%constant long int CD_FRAMESIZE = CDIO_CD_FRAMESIZE; +%constant long int CD_FRAMESIZE_RAW = CDIO_CD_FRAMESIZE_RAW; +%constant long int ISO_BLOCKSIZE = CDIO_CD_FRAMESIZE; +%constant long int M2F2_SECTOR_SIZE = M2F2_SECTOR_SIZE; +%constant long int M2RAW_SECTOR_SIZE = M2RAW_SECTOR_SIZE;