lib/cdio.rb in rbcdio-0.03 vs lib/cdio.rb in rbcdio-0.04

- old
+ new

@@ -1,9 +1,9 @@ #!/usr/bin/env ruby # $Id: cdio.rb,v 1.21 2008/05/02 13:05:40 karl Exp $ # -# Copyright (C) 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org> +# Copyright (C) 2006, 2007, 2008, 2009 Rocky Bernstein <rocky@gnu.org> # # 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 3 of the License, or # (at your option) any later version. @@ -60,939 +60,973 @@ # that cdio is what most people will use. As rubycdio more closely # models the C interface <tt>libcdio</tt>, it is conceivable (if unlikely) # that die-hard libcdio C users who are very familiar with that # interface could prefer that. # - +# require 'rubygems'; require 'ruby-debug'; Debugger.start require "rubycdio" module Cdio -# 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 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 + end + if drc==Rubycdio::DRIVER_OP_NOT_PERMITTED raise DriverUnsupportedError - end - if drc==Rubycdio::DRIVER_OP_BAD_PARAMETER + end + if drc==Rubycdio::DRIVER_OP_BAD_PARAMETER raise DriverBadParameterError - end - if drc==Rubycdio::DRIVER_OP_BAD_POINTER + end + if drc==Rubycdio::DRIVER_OP_BAD_POINTER raise DriverBadPointerError - end - if drc==Rubycdio::DRIVER_OP_NO_DRIVER + end + if drc==Rubycdio::DRIVER_OP_NO_DRIVER raise NoDriverError + end + raise DeviceException('unknown exception %d' % drc) end - raise DeviceException('unknown exception %d' % drc) -end - -# = class DeviceException -# 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, - :"BIN/CUE" => Rubycdio::DRIVER_BINCUE, - :NRG => Rubycdio::DRIVER_NRG, - :device => Rubycdio::DRIVER_DEVICE - } -end - -def read_mode2blocksize() - return { - Rubycdio::READ_MODE_AUDIO => Rubycdio::CD_FRAMESIZE_RAW, - Rubycdio::READ_MODE_M1F1 => Rubycdio::M2RAW_SECTOR_SIZE, - Rubycdio::READ_MODE_M1F2 => Rubycdio::CD_FRAMESIZE, - Rubycdio::READ_MODE_M2F1 => Rubycdio::M2RAW_SECTOR_SIZE, - Rubycdio::READ_MODE_M2F2 => Rubycdio::CD_FRAMESIZE - } -end - - -# 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 - -# Returns: [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 default_device_driver(driver_id=Rubycdio::DRIVER_DEVICE) - return Rubycdio::get_default_device_driver(driver_id) -end - -# Returns: [device1, device2, ...] -# -# Get an list of device names. -def devices(driver_id=Rubycdio::DRIVER_UNKNOWN) - return Rubycdio::get_devices(driver_id) -end - -# Returns: [device1, device2, ... driver_id] -# -# Like get_devices, but return the 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 devices_ret(driver_id=Rubycdio::DRIVER_UNKNOWN) - devices = Rubycdio::get_devices_ret(driver_id) -end - -# 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 nil if we couldn't get a -# default device. It is also possible to return a non nil but after -# dereferencing the the value is nil. This also means nothing was -# found. -def devices_with_cap(capabilities, any=false) - return Rubycdio::get_devices_with_cap(capabilities, any) -end - -# Returns: [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 devices_with_cap_ret(capabilities, any=false) - return Rubycdio::get_devices_with_cap_ret(capabilities, any) -end - -# return bool -# -# Return true if we have driver driver_id. -def driver?(driver_id) - if driver_id.class == Fixnum - return Rubycdio::have_driver(driver_id) == 1 - elsif driver_id.class == Symbol 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 ArgumentError - else - raise ArgumentError + + # = class DeviceException + # General device or driver exceptions + + class DeviceException < Exception end -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 -#-- -# FIXME ? is not quite right -# 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 -#-- -# FIXME ? is not quite right -#++ -# return bin_name for a corresponding CUE file -# -# 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 - -# Returns: 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::device?(source, driver_id) -end - -# Returns: bool -# -# Determine if nrgfile_name is a Nero CD disc image -def nrg?(nrgfile_name) - return Rubycdio::nrg?(nrgfile_name) -end - -# tocfile?(tocfile_name)->bool -# -# Determine if +tocfile_name+ is a cdrdao CD disc image -def tocfile?(tocfile_name) - return Rubycdio::tocfile?(tocfile_name) -end - -# Convert +bitmask+ 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 + # 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, + :"BIN/CUE" => Rubycdio::DRIVER_BINCUE, + :NRG => Rubycdio::DRIVER_NRG, + :device => Rubycdio::DRIVER_DEVICE + } end - if bitmask & Rubycdio::DRIVE_CAP_UNKNOWN - result[:DRIVE_CAP_UNKNOWN] = true + + def read_mode2blocksize() + return { + Rubycdio::READ_MODE_AUDIO => Rubycdio::CD_FRAMESIZE_RAW, + Rubycdio::READ_MODE_M1F1 => Rubycdio::M2RAW_SECTOR_SIZE, + Rubycdio::READ_MODE_M1F2 => Rubycdio::CD_FRAMESIZE, + Rubycdio::READ_MODE_M2F1 => Rubycdio::M2RAW_SECTOR_SIZE, + Rubycdio::READ_MODE_M2F2 => Rubycdio::CD_FRAMESIZE + } 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 +bitmask+ 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 + # 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 - if bitmask & Rubycdio::DRIVE_CAP_WRITE_CD_RW - result[:DRIVE_CAP_WRITE_CD_RW] = true + + # Returns: [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 default_device_driver(driver_id=Rubycdio::DRIVER_DEVICE) + return Rubycdio::get_default_device_driver(driver_id) 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 -# = class Device -# -# CD Input and control class for discs/devices -# -# == SYNOPSIS -# -# require "cdio" -# d = Cdio::Device.new("", Rubycdio::DRIVER_UNKNOWN) -# drive_name = d.device() -# hw = d.hwinfo() -# if hw then -# puts "drive: %s, vendor: %s, model: %s, revision: %s" % -# [drive_name, hw["vendor"], hw["model"], hw["revision"]] -# end -# -# drivers.each_pair { |driver_name, driver_id| -# begin -# if driver?(driver_id): -# puts "Driver %s is installed." % driver_name -# end -# rescue ValueError -# end - -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 + # Returns: [device1, device2, ...] + # + # Get an list of device names. + def devices(driver_id=Rubycdio::DRIVER_UNKNOWN) + return Rubycdio::get_devices(driver_id) end - # Returns: bool + # Returns: [device1, device2, ... driver_id] # - # return true if CD-ROM understand ATAPI commands. - def ATAPI?() - return Rubycdio::ATAPI?(@cd) + # Like get_devices, but return the 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 devices_ret(driver_id=Rubycdio::DRIVER_UNKNOWN) + devices = Rubycdio::get_devices_ret(driver_id) end - - # Returns: status + + # 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. # - # Pause playing CD through analog output. - # A DeviceError exception may be raised. - def audio_pause() - drc=Rubycdio::audio_pause(@cd) - possibly_raise_exception__(drc) + # To find a CD-drive of any type, use the mask Rubycdio::CDIO_FS_MATCH_ALL. + # + # The array of device names is returned or nil if we couldn't get a + # default device. It is also possible to return a non nil but after + # dereferencing the the value is nil. This also means nothing was + # found. + def devices_with_cap(capabilities, any=false) + return Rubycdio::get_devices_with_cap(capabilities, any) end - - # Returns: status - # - # Playing CD through analog output from +start_lsn+ to +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) + + # Returns: [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 devices_with_cap_ret(capabilities, any=false) + return Rubycdio::get_devices_with_cap_ret(capabilities, any) end - # Returns: 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 - - # Returns: 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 - - # Free (C memory) resources associated with the object. Call this when - # done using using CD reading/control operations for the current - # device. - def close() - if @cd - Rubycdio::close(@cd) + # return bool + # + # Return true if we have driver driver_id. + def driver?(driver_id) + if driver_id.class == Fixnum + return Rubycdio::have_driver(driver_id) == 1 + elsif driver_id.class == Symbol 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 ArgumentError else - puts "***No object to close" + raise ArgumentError end - @cd=nil end - # 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) + #-- + # FIXME ? is not quite right + # 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 - - # 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) + + #-- + # FIXME ? is not quite right + #++ + # return bin_name for a corresponding CUE file + # + # 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 - - # Returns: String - # Get the value associatied with key. - def arg(key) - return Rubycdio::get_arg(@cd, key) + # Returns: 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::device?(source, driver_id) end - - # Returns: String - # - # 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 device() - if @cd - return Rubycdio::get_arg(@cd, "source") + + # Returns: bool + # + # Determine if nrgfile_name is a Nero CD disc image + def nrg?(nrgfile_name) + return Rubycdio::nrg?(nrgfile_name) + end + + # tocfile?(tocfile_name)->bool + # + # Determine if +tocfile_name+ is a cdrdao CD disc image + def tocfile?(tocfile_name) + return Rubycdio::tocfile?(tocfile_name) + end + + # Convert +bitmask+ 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 - return Rubycdio::get_device(@cd) + 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 - # Returns: Fixnum - # - # Get the LSN of the end of the CD - # - # DriverError and IOError may raised on error. - def disc_last_lsn() - lsn = Rubycdio::get_disc_last_lsn(@cd) - if lsn == Rubycdio::INVALID_LSN: - raise DriverError + # 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 - return lsn + 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 - - # Returns: String - # - # Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, ...) - # that we've got. The notion of 'CD' is extended a little to include - # DVD's. - def disc_mode() - if not @cd then return "Uninitialized Device" end - return Rubycdio::get_disc_mode(@cd) + + # Convert +bitmask+ 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 - - # Get drive capabilities of device. + + # = class 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) + # CD Input and control class for discs/devices # - # 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 drive_cap() + # == SYNOPSIS + # + # require "cdio" + # d = Cdio::Device.new("", Rubycdio::DRIVER_UNKNOWN) + # drive_name = d.device() + # hw = d.hwinfo() + # if hw then + # puts "drive: %s, vendor: %s, model: %s, revision: %s" % + # [drive_name, hw["vendor"], hw["model"], hw["revision"]] + # end + # + # drivers.each_pair { |driver_name, driver_id| + # begin + # if driver?(driver_id): + # puts "Driver %s is installed." % driver_name + # end + # rescue ValueError + # end + + 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 + + # Returns: bool + # + # return true if CD-ROM understand ATAPI commands. + def ATAPI?() + return Rubycdio::ATAPI?(@cd) + end + + # Returns: 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 + + # Returns: status + # + # Playing CD through analog output from +start_lsn+ to +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 + + # Returns: 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 + + # Returns: 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 + + # Free (C memory) resources associated with the object. 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 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 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 + + # Returns: String + + # Get the value associatied with key. + def arg(key) + return Rubycdio::get_arg(@cd, key) + end + + # Returns: String + # + # 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 device() + if @cd + return Rubycdio::get_arg(@cd, "source") + end + return Rubycdio::get_device(@cd) + end + + # Returns: Fixnum + # + # Get the LSN of the end of the CD + # + # DriverError and IOError may raised on error. + def disc_last_lsn() + lsn = Rubycdio::get_disc_last_lsn(@cd) + if lsn == Rubycdio::INVALID_LSN + raise DriverError + end + return lsn + end + + # Returns: String + # + # Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, ...) + # that we've got. The notion of 'CD' is extended a little to include + # DVD's. + def disc_mode() + if not @cd then return "Uninitialized Device" end + return Rubycdio::get_disc_mode(@cd) + end + + # 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 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 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 = + end + + def 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 - - # Returns: String - # - # return a string containing the name of the driver in use. - # - # An IOError exception is raised on error. - def driver_name() - if not @cd then raise DriverUninitError end - return Rubycdio::get_driver_name(@cd) - end - - # Returns: Fixnum - # - # Return the driver id of the driver in use. - # if object has not been initialized or is nil, - # return Rubycdio::DRIVER_UNKNOWN. - def driver_id() - return Rubycdio::get_driver_id(@cd) - end - - # Returns: Track - # - # return a Track object of the first track. nil is returned - # if there was a problem. - def first_track() - track = Rubycdio::get_first_track_num(@cd) - if track == Rubycdio::INVALID_TRACK - return nil + return [convert_drive_cap_read(b_read_cap), + convert_drive_cap_write(b_write_cap), + convert_drive_cap_misc(b_misc_cap)] end - return Track.new(@cd, track) - end - - # Returns: {"vendor"=>??, "model"=>??, "release"=>??} - # - # Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. - def hwinfo() - return Rubycdio::get_hwinfo(@cd) - end - - # Returns: FixNum - - # Return the Joliet level recognized for cdio. This only makes - # sense for something that has an ISO-9660 filesystem. - - def joliet_level() - return Rubycdio::get_joliet_level(@cd) - end - - # Returns: Fixnum - - # Get the LSN of the first track of the last session of on the CD. - # An exception is thrown on error. - - def last_session() - drc, session = Rubycdio::get_last_session(@cd) - possibly_raise_exception__(drc) - return session - end - - # Returns: Track - # - # return a Track object of the first track. nil is returned - # if there was a problem. - def last_track() - track = Rubycdio::get_last_track_num(@cd) - if track == Rubycdio::INVALID_TRACK + + # Returns: String + # + # return a string containing the name of the driver in use. + # + # An IOError exception is raised on error. + def driver_name() + if not @cd then raise DriverUninitError end + return Rubycdio::get_driver_name(@cd) + end + + # Returns: Fixnum + # + # Return the driver id of the driver in use. + # if object has not been initialized or is nil, + # return Rubycdio::DRIVER_UNKNOWN. + def driver_id() + return Rubycdio::get_driver_id(@cd) + end + + # Returns: Track + # + # return a Track object of the first track. nil is returned + # if there was a problem. + def first_track() + track = Rubycdio::get_first_track_num(@cd) + if track == Rubycdio::INVALID_TRACK return nil + end + return Track.new(@cd, track) end - return Track.new(@cd, track) - end - - # Returns: String - # - # Get the media catalog number (MCN) from the CD. - def mcn() - return Rubycdio::get_mcn(@cd) - end - - # 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 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 - end - - # Returns: Fixnum - # - # Return the number of tracks on the CD. - # A TrackError or IOError exception may be raised on error. - def num_tracks() - track = Rubycdio::get_num_tracks(@cd) - if track == Rubycdio::INVALID_TRACK - raise TrackError + + # Returns: {"vendor"=>??, "model"=>??, "release"=>??} + # + # Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. + def hwinfo() + return Rubycdio::get_hwinfo(@cd) end - return track - end - - # Returns: track - # - # Return a track object for the given track number. - def track(track_num) - return Track.new(@cd, track_num) - end - - # Returns: track - # - # Find the track which contains +lsn+. - # nil is returned if the lsn outside of the CD or - # if there was some error. - # - # If +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 track_for_lsn(lsn) + + # Returns: FixNum + + # Return the Joliet level recognized for cdio. This only makes + # sense for something that has an ISO-9660 filesystem. + + def joliet_level() + return Rubycdio::get_joliet_level(@cd) + end + + # Returns: Fixnum + + # Get the LSN of the first track of the last session of on the CD. + # An exception is thrown on error. + + def last_session() + drc, session = Rubycdio::get_last_session(@cd) + possibly_raise_exception__(drc) + return session + end + + # Returns: Track + # + # return a Track object of the first track. nil is returned + # if there was a problem. + def last_track() track = Rubycdio::get_last_track_num(@cd) - if track == Rubycdio::INVALID_TRACK: + if track == Rubycdio::INVALID_TRACK return nil + end + return Track.new(@cd, track) end - return Track.new(@cd, track) - end - - # Returns: Fixnum - # Reposition read offset - # Similar to (if not the same as) libc's fseek() - # - # +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 - - # 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 the value of +source+, we'll use the default driver device. - # If nil is the value of +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 + + # Returns: String + # + # Get the media catalog number (MCN) from the CD. + def mcn() + return Rubycdio::get_mcn(@cd) end - if not source - source = '' + + # 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 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 end - if not access_mode - access_mode = '' + + # Returns: Fixnum + # + # Return the number of tracks on the CD. + # A TrackError or IOError exception may be raised on error. + def num_tracks() + track = Rubycdio::get_num_tracks(@cd) + if track == Rubycdio::INVALID_TRACK + raise TrackError + end + return track end + + # Returns: track + # + # Return a track object for the given track number. + def track(track_num) + return Track.new(@cd, track_num) + end + + # Returns: track + # + # Find the track which contains +lsn+. + # nil is returned if the lsn outside of the CD or + # if there was some error. + # + # If +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 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 + + # Returns: Fixnum + # Reposition read offset + # Similar to (if not the same as) libc's fseek() + # + # +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 + + # 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 the value of +source+, we'll use the default driver device. + # If nil is the value of +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 - - # Returns: [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 - - # return [size, data] - # - # Reads a number of data sectors (AKA blocks). - # - # +lsn+ is the sector to read; +bytes+ is the number of bytes to read. - # A DeviceError exception may be raised. - def read_data_blocks(lsn, blocks=1) - size = Rubycdio::ISO_BLOCKSIZE*blocks - triple = Rubycdio::read_data_bytes(@cd, lsn, - Rubycdio::ISO_BLOCKSIZE, size) - if not triple - return [-1, nil] + @cd = Rubycdio::open_cd(source, driver_id, access_mode) end + + # Returns: [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 + + # return [size, data] + # + # Reads a number of data sectors (AKA blocks). + # + # +lsn+ is the sector to read; +bytes+ is the number of bytes to read. + # A DeviceError exception may be raised. + def read_data_blocks(lsn, blocks=1) + size = Rubycdio::ISO_BLOCKSIZE*blocks + triple = Rubycdio::read_data_bytes(@cd, lsn, + Rubycdio::ISO_BLOCKSIZE, size) + if not triple + return [-1, nil] + end data, size, drc = triple - possibly_raise_exception__(drc) - return [size, data] - end - - # return [blocks, data] - # - # Reads a number of sectors (AKA blocks). - # - # +lsn+ is the sector to read, +bytes+ is the number of bytes to read. - # - # 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 - return [-1, nil] + possibly_raise_exception__(drc) + return [size, data] end - triple = Rubycdio::read_sectors(@cd, lsn, read_mode, size) - if not triple - return [-1, nil] + + # return [blocks, data] + # + # Reads a number of sectors (AKA blocks). + # + # +lsn+ is the sector to read, +bytes+ is the number of bytes to read. + # + # 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 + return [-1, nil] + end + triple = Rubycdio::read_sectors(@cd, lsn, read_mode, size) + if not triple + return [-1, nil] + end + data, size, drc = triple + possibly_raise_exception__(drc) + blocks = size / blocksize + return [blocks, data] end - data, size, drc = triple - possibly_raise_exception__(drc) - blocks = size / blocksize - return [blocks, data] - end - # Set the blocksize for subsequent reads. - # An exception is thrown on error. - def blocksize=(blocksize) - drc = Rubycdio::set_blocksize(@cd, blocksize) - possibly_raise_exception__(drc) - end - - # Set the drive speed. An exception is thrown on error. - def speed=(speed) - drc = Rubycdio::set_speed(@cd, speed) - possibly_raise_exception__(drc) - end -end # Device + # Set the blocksize for subsequent reads. + # An exception is thrown on error. + def blocksize=(blocksize) + drc = Rubycdio::set_blocksize(@cd, blocksize) + possibly_raise_exception__(drc) + end + + # Set the drive speed. An exception is thrown on error. + def speed=(speed) + drc = Rubycdio::set_speed(@cd, speed) + possibly_raise_exception__(drc) + end + end # Device -# = CD Input and control track class -# -# == SYNOPSIS -# -# require "cdio" -# d = Device.new("/dev/cdrom") -# t = d.first_track() -# first_track = t.track -# num_tracks = d.num_tracks() -# last_track = first_track+num_tracks-1 -# for i in first_track .. last_track -# t = d.track(i) -# puts "%3d: %06u %-6s %s" % [t.track, t.lsn(), t.msf(), t.format()] -# end -# puts "%3X: %06u leadout" % [Rubycdio::CDROM_LEADOUT_TRACK, d.disc_last_lsn()] -# -class Track - - attr_accessor :track - - def initialize(device, track_num) + # = CD Input and control track class + # + # == SYNOPSIS + # + # require "cdio" + # d = Device.new("/dev/cdrom") + # t = d.first_track() + # first_track = t.track + # num_tracks = d.num_tracks() + # last_track = first_track+num_tracks-1 + # for i in first_track .. last_track + # t = d.track(i) + # puts "%3d: %06u %-6s %s" % [t.track, t.lsn(), t.msf(), t.format()] + # end + # puts "%3X: %06u leadout" % [Rubycdio::CDROM_LEADOUT_TRACK, d.disc_last_lsn()] + # + class Track - if track_num.class != Fixnum - raise TrackError('track number parameter is not an integer') + attr_accessor :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 - @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 + # Returns: Fixnum + # + # 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 audio_channels() + channels = Rubycdio::get_track_channels(@device, @track) + if -2 == channels + raise DriverUnsupportedError + elsif -1 == channels + raise TrackError + else + return channels + end end - end - - # Returns: Fixnum - # - # 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 audio_channels() - channels = Rubycdio::get_track_channels(@device, @track) - if -2 == channels - raise DriverUnsupportedError - elsif -1 == channels - raise TrackError - else - return channels + + def cdtext + return CDText.new(Rubycdio::get_cdtext(@device, @track)) end - end - - # Returns: bool - # - # Return copy protection status on a track. Is this meaningful - # not an audio track? - def copy_permit?() - return Rubycdio::track_copy_permit?(@device, @track) - end - - # Returns: format (String) - # - # Get the format (e.g. 'audio', 'mode2', 'mode1') of track. - def format() - return Rubycdio::get_track_format(@device, @track) - end - - # Returns: Fixnum (lsn) - # - # Return the ending LSN for a track. - # A TrackError or IOError exception may be raised on error. - def last_lsn() - lsn = Rubycdio::get_track_last_lsn(@device, @track) - if lsn == Rubycdio::INVALID_LSN - raise TrackError('Invalid LSN returned') + + # Returns: bool + # + # Return copy protection status on a track. Is this meaningful + # not an audio track? + def copy_permit?() + return Rubycdio::track_copy_permit?(@device, @track) end - return lsn - end - - # Returns: Fixnum (lba) - # - # Return the starting LBA for a track - # A TrackError exception is raised on error. - def lba() - lba = Rubycdio::get_track_lba(@device, @track) - if lba == Rubycdio::INVALID_LBA - raise TrackError('Invalid LBA returned') + + # Returns: format (String) + # + # Get the format (e.g. 'audio', 'mode2', 'mode1') of track. + def format() + return Rubycdio::get_track_format(@device, @track) end - return lba - end - - # Returns: Fixnum (lsn) - # - # Return the starting LSN for a track - # A TrackError exception is raised on error. - def lsn() - lsn = Rubycdio::get_track_lsn(@device, @track) - if lsn == Rubycdio::INVALID_LSN: + + # Returns: Fixnum (lsn) + # + # Return the ending LSN for a track. + # A TrackError or IOError exception may be raised on error. + def last_lsn() + lsn = Rubycdio::get_track_last_lsn(@device, @track) + if lsn == Rubycdio::INVALID_LSN raise TrackError('Invalid LSN returned') + end + return lsn end - return lsn - end - - # Returns: String - # - # 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 <i>mm:ss:ff</i> if all good, or string nil on - # error. - def msf() - return Rubycdio::get_track_msf(@device, @track) - end - - # Returns: String - # - # 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 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 + + # Returns: Fixnum (lba) + # + # Return the starting LBA for a track + # A TrackError exception is raised on error. + def lba() + lba = Rubycdio::get_track_lba(@device, @track) + if lba == Rubycdio::INVALID_LBA + raise TrackError('Invalid LBA returned') + end + return lba end + + # Returns: Fixnum (lsn) + # + # Return the starting LSN for a track + # A TrackError exception is raised on error. + def lsn() + lsn = Rubycdio::get_track_lsn(@device, @track) + if lsn == Rubycdio::INVALID_LSN + raise TrackError('Invalid LSN returned') + end + return lsn + end + + # Returns: String + # + # 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 <i>mm:ss:ff</i> if all good, or string nil on + # error. + def msf() + return Rubycdio::get_track_msf(@device, @track) + end + + # Returns: String + # + # 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 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 - # Returns: Fixnum - # - # 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. + # Returns: Fixnum + # + # 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 sec_count() - sec_count = Rubycdio::get_track_sec_count(@device, @track) - if sec_count == 0 - raise TrackError - end - return sec_count + sec_count = Rubycdio::get_track_sec_count(@device, @track) + if sec_count == 0 + raise TrackError + end + return sec_count end - + # 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::track_green?(@device, @track) end end # class Track -end # Cdio + class CDText + def initialize(opaque) + @_cdtext = opaque + end + + # + # get(self, key)->string + # + # Get the value associatied with key. + # + def get(key) + return Rubycdio::cdtext_get(key, @_cdtext) + end + + def is_keyword(key) + return Rubycdio::cdtext_is_keyword(key, @_cdtext) + end + + # + # set(self, key, string)->None + # + # Set the value associatied with key. + # + def set( key, string) + return Rubycdio::cdtext_set(key, string, @_cdtext) + end + + + end +end # module Cdio + include Cdio # # Local variables: # mode: Ruby # End: