rbcdio 0.01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +340 -0
  3. data/ChangeLog +315 -0
  4. data/INSTALL +236 -0
  5. data/Makefile.am +163 -0
  6. data/Makefile.in +557 -0
  7. data/NEWS +5 -0
  8. data/README +75 -0
  9. data/Rakefile +234 -0
  10. data/THANKS +3 -0
  11. data/VERSION +1 -0
  12. data/VERSION.in +1 -0
  13. data/config.guess +1473 -0
  14. data/config.sub +1576 -0
  15. data/configure +4802 -0
  16. data/configure.ac +158 -0
  17. data/data/copying.iso +0 -0
  18. data/data/isofs-m1.bin +0 -0
  19. data/data/isofs-m1.cue +3 -0
  20. data/doc/created.rid +1 -0
  21. data/doc/fr_class_index.html +42 -0
  22. data/doc/fr_file_index.html +40 -0
  23. data/doc/fr_method_index.html +133 -0
  24. data/doc/index.html +24 -0
  25. data/doc/rdoc-style.css +208 -0
  26. data/example/COPYING +340 -0
  27. data/example/README +47 -0
  28. data/example/audio.rb +186 -0
  29. data/example/cd-read.rb +167 -0
  30. data/example/copying +340 -0
  31. data/example/device.rb +91 -0
  32. data/example/drivers.rb +63 -0
  33. data/example/drives.rb +63 -0
  34. data/example/eject.rb +69 -0
  35. data/example/iso1.rb +89 -0
  36. data/example/iso2.rb +106 -0
  37. data/example/iso3.rb +111 -0
  38. data/example/tracks.rb +83 -0
  39. data/ext/cdio/Makefile +139 -0
  40. data/ext/cdio/extconf.rb +9 -0
  41. data/ext/cdio/rubycdio_wrap.c +3410 -0
  42. data/ext/iso9660/Makefile +139 -0
  43. data/ext/iso9660/extconf.rb +10 -0
  44. data/ext/iso9660/rubyiso9660_wrap.c +3005 -0
  45. data/install-sh +323 -0
  46. data/lib/Makefile +7 -0
  47. data/lib/cdio.rb +1000 -0
  48. data/lib/iso9660.rb +566 -0
  49. data/missing +360 -0
  50. data/rubycdio.m4 +14 -0
  51. data/swig/Makefile +7 -0
  52. data/swig/audio.swg +63 -0
  53. data/swig/compat.swg +104 -0
  54. data/swig/device.swg +513 -0
  55. data/swig/device_const.swg +144 -0
  56. data/swig/disc.swg +96 -0
  57. data/swig/read.swg +164 -0
  58. data/swig/rubycdio.swg +86 -0
  59. data/swig/rubyiso9660.swg +827 -0
  60. data/swig/track.swg +206 -0
  61. data/swig/types.swg +65 -0
  62. data/test/Makefile +7 -0
  63. data/test/Rakefile +8 -0
  64. data/test/cdda.bin +0 -0
  65. data/test/cdda.cue +7 -0
  66. data/test/cdda.toc +14 -0
  67. data/test/cdiotest.rb +228 -0
  68. data/test/isocopy.rb +394 -0
  69. data/test/isotest.rb +187 -0
  70. metadata +116 -0
data/lib/cdio.rb ADDED
@@ -0,0 +1,1000 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id: cdio.rb,v 1.18 2006/12/16 13:24:48 rocky Exp $
3
+ #
4
+ # Copyright (C) 2006 Rocky Bernstein <rocky@gnu.org>
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
+ # 02110-1301 USA.
20
+ #
21
+ # Author:: Rocky Bernstein (mailto:rocky@gnu.org)
22
+ #
23
+ # = cdio
24
+ # Module for CD Input and Control library.
25
+ # == Version
26
+ # :include:VERSION
27
+ #
28
+ # == SYNOPSIS
29
+ #
30
+ # The CD Input and Control library (pycdio) encapsulates CD-ROM
31
+ # reading and control. Applications wishing to be oblivious of the OS-
32
+ # and device-dependent properties of a CD-ROM can use this library.
33
+ #
34
+ # require "cdio'
35
+ #
36
+ # cd_drives = Cdio::devices(Rubycdio::DRIVER_DEVICE)
37
+ # for drive in cd_drives
38
+ # puts "Drive %s" % drive
39
+ # end
40
+ # drivers.each_pair { |driver_name, driver_id|
41
+ # if Cdio::driver?(driver_id):
42
+ # puts "Driver %s is installed." % driver_name
43
+ # end
44
+ #
45
+ #
46
+ # == DESCRIPTION
47
+ #
48
+ #
49
+ # This is an Ruby interface to the GNU CD Input and Control library,
50
+ # <tt>libcdio</tt>, written in C. The library encapsulates CD-ROM reading
51
+ # and control. Ruby programs wishing to be oblivious of the OS- and
52
+ # device-dependent properties of a CD-ROM can use this library.
53
+ #
54
+ #
55
+ # The encapsulation is done in two parts. The lower-level Ruby
56
+ # module is called rubycdio and is generated by SWIG.
57
+ #
58
+ # This module uses rubycdio. Actually, there are no objects in
59
+ # module, but there are in classes Device and Track.
60
+ #
61
+ # Although <tt>rubycdio</tt> is perfectly usable on its own, it is expected
62
+ # that cdio is what most people will use. As rubycdio more closely
63
+ # models the C interface <tt>libcdio</tt>, it is conceivable (if unlikely)
64
+ # that die-hard libcdio C users who are very familiar with that
65
+ # interface could prefer that.
66
+ #
67
+
68
+ require "rubycdio"
69
+
70
+ module Cdio
71
+
72
+ # Raise a Driver Error exception on error as determined by drc
73
+ def possibly_raise_exception__(drc, msg=nil)
74
+ if drc==Rubycdio::DRIVER_OP_SUCCESS
75
+ return
76
+ end
77
+ if drc==Rubycdio::DRIVER_OP_ERROR
78
+ raise DriverError
79
+ end
80
+ if drc==Rubycdio::DRIVER_OP_UNINIT
81
+ raise DriverUninitError
82
+ end
83
+ if drc==Rubycdio::DRIVER_OP_UNSUPPORTED
84
+ raise DriverUnsupportedError
85
+ end
86
+ if drc==Rubycdio::DRIVER_OP_NOT_PERMITTED
87
+ raise DriverUnsupportedError
88
+ end
89
+ if drc==Rubycdio::DRIVER_OP_BAD_PARAMETER
90
+ raise DriverBadParameterError
91
+ end
92
+ if drc==Rubycdio::DRIVER_OP_BAD_POINTER
93
+ raise DriverBadPointerError
94
+ end
95
+ if drc==Rubycdio::DRIVER_OP_NO_DRIVER
96
+ raise NoDriverError
97
+ end
98
+ raise DeviceException('unknown exception %d' % drc)
99
+ end
100
+
101
+ # = class DeviceException
102
+ # General device or driver exceptions
103
+
104
+ class DeviceException < Exception
105
+ end
106
+
107
+ class DriverError < DeviceException; end
108
+ class DriverUnsupportedError < DeviceException; end
109
+ class DriverUninitError < DeviceException; end
110
+ class DriverNotPermittedError < DeviceException; end
111
+ class DriverBadParameterError < DeviceException; end
112
+ class DriverBadPointerError < DeviceException; end
113
+ class NoDriverError < DeviceException; end
114
+
115
+ class TrackError < DeviceException; end
116
+
117
+
118
+ # Note: the keys below match those the names returned by
119
+ # cdio_get_driver_name().
120
+ def drivers()
121
+ return {
122
+ :"Unknown" => Rubycdio::DRIVER_UNKNOWN,
123
+ :"AIX" => Rubycdio::DRIVER_AIX,
124
+ :"BSDI" => Rubycdio::DRIVER_BSDI,
125
+ :"FreeBSD" => Rubycdio::DRIVER_FREEBSD,
126
+ :"GNU/Linux" => Rubycdio::DRIVER_LINUX,
127
+ :"Solaris" => Rubycdio::DRIVER_SOLARIS,
128
+ :"OS X" => Rubycdio::DRIVER_OSX,
129
+ :"WIN32" => Rubycdio::DRIVER_WIN32,
130
+ :"CDRDAO" => Rubycdio::DRIVER_CDRDAO,
131
+ :"BIN/CUE" => Rubycdio::DRIVER_BINCUE,
132
+ :"NRG" => Rubycdio::DRIVER_NRG,
133
+ :"device" => Rubycdio::DRIVER_DEVICE
134
+ }
135
+ end
136
+
137
+ def read_mode2blocksize()
138
+ return {
139
+ Rubycdio::READ_MODE_AUDIO => Rubycdio::CD_FRAMESIZE_RAW,
140
+ Rubycdio::READ_MODE_M1F1 => Rubycdio::M2RAW_SECTOR_SIZE,
141
+ Rubycdio::READ_MODE_M1F2 => Rubycdio::CD_FRAMESIZE,
142
+ Rubycdio::READ_MODE_M2F1 => Rubycdio::M2RAW_SECTOR_SIZE,
143
+ Rubycdio::READ_MODE_M2F2 => Rubycdio::CD_FRAMESIZE
144
+ }
145
+ end
146
+
147
+
148
+ # close media tray in CD drive if there is a routine to do so.
149
+ # The driver id is returned. A DeviceException is thrown on error.
150
+ def close_tray(drive=nil, driver_id=Rubycdio::DRIVER_UNKNOWN)
151
+ drc, found_driver_id = Rubycdio::close_tray(drive, driver_id)
152
+ possibly_raise_exception__(drc)
153
+ return found_driver_id
154
+ end
155
+
156
+ # Returns: [device, driver]
157
+ #
158
+ # Return a string containing the default CD device if none is
159
+ # specified. if driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE
160
+ # then one set the default device for that.
161
+ #
162
+ # nil is returned as the device if we couldn't get a default
163
+ # device.
164
+ def default_device_driver(driver_id=Rubycdio::DRIVER_DEVICE)
165
+ return Rubycdio::get_default_device_driver(driver_id)
166
+ end
167
+
168
+ # Returns: [device1, device2, ...]
169
+ #
170
+ # Get an list of device names.
171
+ def devices(driver_id=Rubycdio::DRIVER_UNKNOWN)
172
+ return Rubycdio::get_devices(driver_id)
173
+ end
174
+
175
+ # Returns: [device1, device2, ... driver_id]
176
+ #
177
+ # Like get_devices, but return the p_driver_id which may be different
178
+ # from the passed-in driver_id if it was Rubycdio::DRIVER_DEVICE or
179
+ # Rubycdio::DRIVER_UNKNOWN. The return driver_id may be useful because
180
+ # often one wants to get a drive name and then *open* it
181
+ # afterwards. Giving the driver back facilitates this, and speeds things
182
+ # up for libcdio as well.
183
+ def devices_ret(driver_id=Rubycdio::DRIVER_UNKNOWN)
184
+ devices = Rubycdio::get_devices_ret(driver_id)
185
+ end
186
+
187
+ # Get an array of device names in search_devices that have at least
188
+ # the capabilities listed by the capabities parameter.
189
+ #
190
+ # If any is false then every capability listed in the
191
+ # extended portion of capabilities (i.e. not the basic filesystem)
192
+ # must be satisified. If any is true, then if any of the
193
+ # capabilities matches, we call that a success.
194
+ #
195
+ # To find a CD-drive of any type, use the mask Rubycdio::CDIO_FS_MATCH_ALL.
196
+ #
197
+ # The array of device names is returned or NULL if we couldn't get a
198
+ # default device. It is also possible to return a non NULL but after
199
+ # dereferencing the the value is NULL. This also means nothing was
200
+ # found.
201
+ def devices_with_cap(capabilities, any=false)
202
+ return Rubycdio::get_devices_with_cap(capabilities, any)
203
+ end
204
+
205
+ # Returns: [device1, device2..., driver_id]
206
+ #
207
+ # Like cdio_get_devices_with_cap but we return the driver we found
208
+ # as well. This is because often one wants to search for kind of drive
209
+ # and then *open* it afterwards. Giving the driver back facilitates this,
210
+ # and speeds things up for libcdio as well.
211
+ def devices_with_cap_ret(capabilities, any=false)
212
+ return Rubycdio::get_devices_with_cap_ret(capabilities, any)
213
+ end
214
+
215
+ # return bool
216
+ #
217
+ # Return true if we have driver driver_id.
218
+ def driver?(driver_id)
219
+ if driver_id.class == Fixnum
220
+ return Rubycdio::have_driver(driver_id) == 1
221
+ elsif driver_id.class == Symbol and drivers.member?(driver_id)
222
+ ret = Rubycdio::have_driver(drivers[driver_id])
223
+ if ret == 0 then return false end
224
+ if ret == 1 then return true end
225
+ raise ArgumentError
226
+ else
227
+ raise ArgumentError
228
+ end
229
+ end
230
+
231
+ #--
232
+ # FIXME ? is not quite right
233
+ # binfile?(binfile_name)->cue_name
234
+ #++
235
+ #
236
+ # Determine if binfile_name is the BIN file part of a CDRWIN CD
237
+ # disk image.
238
+ #
239
+ # Return the corresponding CUE file if bin_name is a BIN file or
240
+ # nil if not a BIN file.
241
+ def binfile?(binfile_name)
242
+ return Rubycdio::is_binfile(binfile_name)
243
+ end
244
+
245
+ #--
246
+ # FIXME ? is not quite right
247
+ #++
248
+ # return bin_name
249
+ #
250
+ # Determine if cuefile_name is the CUE file part of a CDRWIN CD
251
+ # disk image.
252
+ #
253
+ # Return the corresponding BIN file if bin_name is a CUE file or
254
+ # nil if not a CUE file.
255
+ def cuefile?(cuefile_name)
256
+ return Rubycdio::is_cuefile(cuefile_name)
257
+ end
258
+
259
+ # Returns: bool
260
+ #
261
+ # Return true if source refers to a real hardware CD-ROM.
262
+ def device?(source, driver_id=Rubycdio::DRIVER_UNKNOWN)
263
+ if not driver_id then driver_id=Rubycdio::DRIVER_UNKNOWN end
264
+ return Rubycdio::device?(source, driver_id)
265
+ end
266
+
267
+ # Returns: bool
268
+ #
269
+ # Determine if nrgfile_name is a Nero CD disc image
270
+ def nrg?(nrgfile_name)
271
+ return Rubycdio::nrg?(nrgfile_name)
272
+ end
273
+
274
+ # tocfile?(tocfile_name)->bool
275
+ #
276
+ # Determine if tocfile_name is a cdrdao CD disc image
277
+ def tocfile?(tocfile_name)
278
+ return Rubycdio::tocfile?(tocfile_name)
279
+ end
280
+
281
+ # Convert bit mask for miscellaneous drive properties
282
+ # into a dictionary of drive capabilities
283
+ def convert_drive_cap_misc(bitmask)
284
+ result={}
285
+ if bitmask & Rubycdio::DRIVE_CAP_ERROR
286
+ result[:DRIVE_CAP_ERROR] = true
287
+ end
288
+ if bitmask & Rubycdio::DRIVE_CAP_UNKNOWN
289
+ result[:DRIVE_CAP_UNKNOWN] = true
290
+ end
291
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_CLOSE_TRAY
292
+ result[:DRIVE_CAP_MISC_CLOSE_TRAY] = true
293
+ end
294
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_EJECT
295
+ result[:DRIVE_CAP_MISC_EJECT] = true
296
+ end
297
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_LOCK
298
+ result['DRIVE_CAP_MISC_LOCK'] = true
299
+ end
300
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_SELECT_SPEED
301
+ result[:DRIVE_CAP_MISC_SELECT_SPEED] = true
302
+ end
303
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_SELECT_DISC
304
+ result[:DRIVE_CAP_MISC_SELECT_DISC] = true
305
+ end
306
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_MULTI_SESSION
307
+ result[:DRIVE_CAP_MISC_MULTI_SESSION] = true
308
+ end
309
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_MEDIA_CHANGED
310
+ result[:DRIVE_CAP_MISC_MEDIA_CHANGED] = true
311
+ end
312
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_RESET
313
+ result[:DRIVE_CAP_MISC_RESET] = true
314
+ end
315
+ if bitmask & Rubycdio::DRIVE_CAP_MISC_FILE
316
+ result[:DRIVE_CAP_MISC_FILE] = true
317
+ end
318
+ return result
319
+ end
320
+
321
+ # Convert bit mask for drive read properties
322
+ # into a dictionary of drive capabilities
323
+ def convert_drive_cap_read(bitmask)
324
+ result={}
325
+ if bitmask & Rubycdio::DRIVE_CAP_READ_AUDIO
326
+ result[:DRIVE_CAP_READ_AUDIO] = true
327
+ end
328
+ if bitmask & Rubycdio::DRIVE_CAP_READ_CD_DA
329
+ result[:DRIVE_CAP_READ_CD_DA] = true
330
+ end
331
+ if bitmask & Rubycdio::DRIVE_CAP_READ_CD_G
332
+ result[:DRIVE_CAP_READ_CD_G] = true
333
+ end
334
+ if bitmask & Rubycdio::DRIVE_CAP_READ_CD_R
335
+ result[:DRIVE_CAP_READ_CD_R] = true
336
+ end
337
+ if bitmask & Rubycdio::DRIVE_CAP_READ_CD_RW
338
+ result[:DRIVE_CAP_READ_CD_RW] = true
339
+ end
340
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_R
341
+ result[:DRIVE_CAP_READ_DVD_R] = true
342
+ end
343
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_PR
344
+ result[:DRIVE_CAP_READ_DVD_PR] = true
345
+ end
346
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RAM
347
+ result[:DRIVE_CAP_READ_DVD_RAM] = true
348
+ end
349
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_ROM
350
+ result[:DRIVE_CAP_READ_DVD_ROM] = true
351
+ end
352
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RW
353
+ result[:DRIVE_CAP_READ_DVD_RW] = true
354
+ end
355
+ if bitmask & Rubycdio::DRIVE_CAP_READ_DVD_RPW
356
+ result[:DRIVE_CAP_READ_DVD_RPW] = true
357
+ end
358
+ if bitmask & Rubycdio::DRIVE_CAP_READ_C2_ERRS
359
+ result[:DRIVE_CAP_READ_C2_ERRS] = true
360
+ end
361
+ if bitmask & Rubycdio::DRIVE_CAP_READ_MODE2_FORM1
362
+ result[:DRIVE_CAP_READ_MODE2_FORM1] = true
363
+ end
364
+ if bitmask & Rubycdio::DRIVE_CAP_READ_MODE2_FORM2
365
+ result[:DRIVE_CAP_READ_MODE2_FORM2] = true
366
+ end
367
+ if bitmask & Rubycdio::DRIVE_CAP_READ_MCN
368
+ result[:DRIVE_CAP_READ_MCN] = true
369
+ end
370
+ if bitmask & Rubycdio::DRIVE_CAP_READ_ISRC
371
+ result[:DRIVE_CAP_READ_ISRC] = true
372
+ end
373
+ return result
374
+ end
375
+
376
+ # Convert bit mask for drive write properties
377
+ # into a dictionary of drive capabilities
378
+ def convert_drive_cap_write(bitmask)
379
+ result={}
380
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_CD_R
381
+ result[:DRIVE_CAP_WRITE_CD_R] = true
382
+ end
383
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_CD_RW
384
+ result[:DRIVE_CAP_WRITE_CD_RW] = true
385
+ end
386
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_R
387
+ result[:DRIVE_CAP_WRITE_DVD_R] = true
388
+ end
389
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_PR
390
+ result[:DRIVE_CAP_WRITE_DVD_PR] = true
391
+ end
392
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RAM
393
+ result[:DRIVE_CAP_WRITE_DVD_RAM] = true
394
+ end
395
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RW
396
+ result[:DRIVE_CAP_WRITE_DVD_RW] = true
397
+ end
398
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_DVD_RPW
399
+ result[:DRIVE_CAP_WRITE_DVD_RPW] = true
400
+ end
401
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_MT_RAINIER
402
+ result[:DRIVE_CAP_WRITE_MT_RAINIER] = true
403
+ end
404
+ if bitmask & Rubycdio::DRIVE_CAP_WRITE_BURN_PROOF
405
+ result[:DRIVE_CAP_WRITE_BURN_PROOF] = true
406
+ end
407
+ return result
408
+ end
409
+
410
+ # = class Device
411
+ #
412
+ # CD Input and control class for discs/devices
413
+ #
414
+ # == SYNOPSIS
415
+ #
416
+ # require "cdio"
417
+ # d = Cdio::Device.new("", Rubycdio::DRIVER_UNKNOWN)
418
+ # drive_name = d.device()
419
+ # hw = d.hwinfo()
420
+ # if hw then
421
+ # puts "drive: %s, vendor: %s, model: %s, revision: %s" %
422
+ # [drive_name, hw["vendor"], hw["model"], hw["revision"]]
423
+ # end
424
+ #
425
+ # drivers.each_pair { |driver_name, driver_id|
426
+ # begin
427
+ # if driver?(driver_id):
428
+ # puts "Driver %s is installed." % driver_name
429
+ # end
430
+ # rescue ValueError
431
+ # end
432
+
433
+ class Device
434
+
435
+ def initialize(source=nil, driver_id=nil,
436
+ access_mode=nil)
437
+ @cd = nil
438
+ if source or driver_id
439
+ open(source, driver_id, access_mode)
440
+ end
441
+ end
442
+
443
+ # Returns: bool
444
+ #
445
+ # return true if CD-ROM understand ATAPI commands.
446
+ def ATAPI?()
447
+ return Rubycdio::ATAPI?(@cd)
448
+ end
449
+
450
+ # Returns: status
451
+ #
452
+ # Pause playing CD through analog output.
453
+ # A DeviceError exception may be raised.
454
+ def audio_pause()
455
+ drc=Rubycdio::audio_pause(@cd)
456
+ possibly_raise_exception__(drc)
457
+ end
458
+
459
+ # Returns: status
460
+ #
461
+ # Playing CD through analog output at the given lsn to the ending lsn
462
+ # A DeviceError exception may be raised.
463
+ def audio_play_lsn(start_lsn, end_lsn)
464
+ drc=Rubycdio::audio_play_lsn(@cd, start_lsn, end_lsn)
465
+ possibly_raise_exception__(drc)
466
+ end
467
+
468
+ # Returns: status
469
+ #
470
+ # Resume playing an audio CD through the analog interface.
471
+ # A DeviceError exception may be raised.
472
+ def audio_resume()
473
+ drc=Rubycdio::audio_resume(@cd)
474
+ possibly_raise_exception__(drc)
475
+ end
476
+
477
+ # Returns: status
478
+ #
479
+ # Stop playing an audio CD through the analog interface.
480
+ # A DeviceError exception may be raised.
481
+ def audio_stop()
482
+ drc=Rubycdio::audio_stop(@cd)
483
+ possibly_raise_exception__(drc)
484
+ end
485
+
486
+ # Free resources associated with p_cdio. Call this when done using
487
+ # using CD reading/control operations for the current device.
488
+ def close()
489
+ if @cd
490
+ Rubycdio::close(@cd)
491
+ else
492
+ puts "***No object to close"
493
+ end
494
+ @cd=nil
495
+ end
496
+
497
+ # Eject media in CD drive if there is a routine to do so.
498
+ # A DeviceError exception may be raised.
499
+ def eject_media()
500
+ drc=Rubycdio::eject_media(@cd)
501
+ @cd = nil
502
+ possibly_raise_exception__(drc)
503
+ end
504
+
505
+ # Eject media in CD drive if there is a routine to do so.
506
+ # An exception is thrown on error.
507
+ def eject_media_drive(drive=nil)
508
+ ### FIXME: combine into above by testing if drive is the string
509
+ ### nil versus drive = Rubycdio::DRIVER_UNKNOWN
510
+ Rubycdio::eject_media_drive(drive)
511
+ end
512
+
513
+ # Returns: String
514
+
515
+ # Get the value associatied with key.
516
+ def arg(key)
517
+ return Rubycdio::get_arg(@cd, key)
518
+ end
519
+
520
+ # Returns: String
521
+ #
522
+ # Get the default CD device.
523
+ # If we haven't initialized a specific device driver),
524
+ # then find a suitable one and return the default device for that.
525
+ # In some situations of drivers or OS's we can't find a CD device if
526
+ # there is no media in it and it is possible for this routine to return
527
+ # nil even though there may be a hardware CD-ROM.
528
+ def device()
529
+ if @cd
530
+ return Rubycdio::get_arg(@cd, "source")
531
+ end
532
+ return Rubycdio::get_device(@cd)
533
+ end
534
+
535
+ # Returns: Fixnum
536
+ #
537
+ # Get the LSN of the end of the CD
538
+ #
539
+ # DriverError and IOError may raised on error.
540
+ def disc_last_lsn()
541
+ lsn = Rubycdio::get_disc_last_lsn(@cd)
542
+ if lsn == Rubycdio::INVALID_LSN:
543
+ raise DriverError
544
+ end
545
+ return lsn
546
+ end
547
+
548
+ # Returns: String
549
+ #
550
+ # Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, ...)
551
+ # that we've got. The notion of 'CD' is extended a little to include
552
+ # DVD's.
553
+ def disc_mode()
554
+ if not @cd then return "Uninitialized Device" end
555
+ return Rubycdio::get_disc_mode(@cd)
556
+ end
557
+
558
+ # Get drive capabilities of device.
559
+ #
560
+ # In some situations of drivers or OS's we can't find a CD
561
+ # device if there is no media in it. In this situation
562
+ # capabilities will show up as empty even though there is a
563
+ # hardware CD-ROM. get_drive_cap_dev()->(read_cap, write_cap,
564
+ # misc_cap)
565
+ #
566
+ # Get drive capabilities of device.
567
+ #
568
+ # In some situations of drivers or OS's we can't find a CD
569
+ # device if there is no media in it. In this situation
570
+ # capabilities will show up as empty even though there is a
571
+ # hardware CD-ROM.
572
+ def drive_cap()
573
+ b_read_cap, b_write_cap, b_misc_cap = Rubycdio::get_drive_cap(@cd)
574
+ return [convert_drive_cap_read(b_read_cap),
575
+ convert_drive_cap_write(b_write_cap),
576
+ convert_drive_cap_misc(b_misc_cap)]
577
+ end
578
+
579
+ def drive_cap_dev(device=nil)
580
+ #---
581
+ ### FIXME: combine into above by testing on the type of device.
582
+ #+++
583
+ b_read_cap, b_write_cap, b_misc_cap =
584
+ Rubycdio::get_drive_cap_dev(device);
585
+ return [convert_drive_cap_read(b_read_cap),
586
+ convert_drive_cap_write(b_write_cap),
587
+ convert_drive_cap_misc(b_misc_cap)]
588
+ end
589
+
590
+ # Returns: String
591
+ #
592
+ # return a string containing the name of the driver in use.
593
+ #
594
+ # An IOError exception is raised on error.
595
+ def driver_name()
596
+ if not @cd then raise DriverUninitError end
597
+ return Rubycdio::get_driver_name(@cd)
598
+ end
599
+
600
+ # Returns: Fixnum
601
+ #
602
+ # Return the driver id of the driver in use.
603
+ # if object has not been initialized or is nil,
604
+ # return Rubycdio::DRIVER_UNKNOWN.
605
+ def driver_id()
606
+ return Rubycdio::get_driver_id(@cd)
607
+ end
608
+
609
+ # Returns: Track
610
+ #
611
+ # return a Track object of the first track. nil is returned
612
+ # if there was a problem.
613
+ def first_track()
614
+ track = Rubycdio::get_first_track_num(@cd)
615
+ if track == Rubycdio::INVALID_TRACK
616
+ return nil
617
+ end
618
+ return Track.new(@cd, track)
619
+ end
620
+
621
+ # Returns: {"vendor"=>??, "model"=>??, "release"=>??}
622
+ #
623
+ # Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
624
+ def hwinfo()
625
+ return Rubycdio::get_hwinfo(@cd)
626
+ end
627
+
628
+ # Returns: FixNum
629
+
630
+ # Return the Joliet level recognized for cdio. This only makes
631
+ # sense for something that has an ISO-9660 filesystem.
632
+
633
+ def joliet_level()
634
+ return Rubycdio::get_joliet_level(@cd)
635
+ end
636
+
637
+ # Returns: Fixnum
638
+
639
+ # Get the LSN of the first track of the last session of on the CD.
640
+ # An exception is thrown on error.
641
+
642
+ def last_session()
643
+ drc, session = Rubycdio::get_last_session(@cd)
644
+ possibly_raise_exception__(drc)
645
+ return session
646
+ end
647
+
648
+ # Returns: Track
649
+ #
650
+ # return a Track object of the first track. nil is returned
651
+ # if there was a problem.
652
+ def last_track()
653
+ track = Rubycdio::get_last_track_num(@cd)
654
+ if track == Rubycdio::INVALID_TRACK
655
+ return nil
656
+ end
657
+ return Track.new(@cd, track)
658
+ end
659
+
660
+ # Returns: String
661
+ #
662
+ # Get the media catalog number (MCN) from the CD.
663
+ def mcn()
664
+ return Rubycdio::get_mcn(@cd)
665
+ end
666
+
667
+ # Find out if media has changed since the last call.
668
+ # Return true if media has changed since last call. An exception
669
+ # Error is given on error.
670
+ def media_changed?()
671
+ drc = Rubycdio::get_media_changed(@cd)
672
+ if drc == 0 then return false end
673
+ if drc == 1 then return true end
674
+ possibly_raise_exception__(drc)
675
+ raise DeviceException
676
+ end
677
+
678
+ # Returns: Fixnum
679
+ #
680
+ # Return the number of tracks on the CD.
681
+ # A TrackError or IOError exception may be raised on error.
682
+ def num_tracks()
683
+ track = Rubycdio::get_num_tracks(@cd)
684
+ if track == Rubycdio::INVALID_TRACK
685
+ raise TrackError
686
+ end
687
+ return track
688
+ end
689
+
690
+ # Returns: track
691
+ #
692
+ # Return a track object for the given track number.
693
+ def track(track_num)
694
+ return Track.new(@cd, track_num)
695
+ end
696
+
697
+ # Returns: track
698
+ #
699
+ # Find the track which contains lsn.
700
+ # nil is returned if the lsn outside of the CD or
701
+ # if there was some error.
702
+ #
703
+ # If the lsn is before the pregap of the first track,
704
+ # A track object with a 0 track is returned.
705
+ # Otherwise we return the track that spans the lsn.
706
+ def track_for_lsn(lsn)
707
+ track = Rubycdio::get_last_track_num(@cd)
708
+ if track == Rubycdio::INVALID_TRACK:
709
+ return nil
710
+ end
711
+ return Track.new(@cd, track)
712
+ end
713
+
714
+ # Returns: Fixnum
715
+ # Reposition read offset
716
+ # Similar to (if not the same as) libc's fseek()
717
+ #
718
+ # cdio is object to get adjested, offset is amount to seek and
719
+ # whence is like corresponding parameter in libc's lseek, e.g.
720
+ # it should be SEEK_SET or SEEK_END.
721
+ #
722
+ # the offset is returned or -1 on error.
723
+ def lseek(offset, whence)
724
+ return Rubycdio::lseek(@cd, offset, whence)
725
+ end
726
+
727
+ # Sets up to read from place specified by source, driver_id and
728
+ # access mode. This should be called before using any other routine
729
+ # except those that act on a CD-ROM drive by name.
730
+ #
731
+ # If nil is given as the source, we'll use the default driver device.
732
+ # If nil is given as the driver_id, we'll find a suitable device driver.
733
+ #
734
+ # If device object was, previously opened it is closed first.
735
+ #
736
+ # Device is opened so that subsequent operations can be performed.
737
+ def open(source=nil, driver_id=Rubycdio::DRIVER_UNKNOWN,
738
+ access_mode=nil)
739
+ if not driver_id
740
+ driver_id=Rubycdio::DRIVER_UNKNOWN
741
+ end
742
+ if not source
743
+ source = ''
744
+ end
745
+ if not access_mode
746
+ access_mode = ''
747
+ end
748
+ if @cd
749
+ close()
750
+ end
751
+ @cd = Rubycdio::open_cd(source, driver_id, access_mode)
752
+ end
753
+
754
+ # Returns: [size, data]
755
+ #
756
+ # Reads the next size bytes.
757
+ # Similar to (if not the same as) libc's read()
758
+ #
759
+ # The number of bytes read and the data is returned.
760
+ # A DeviceError exception may be raised.
761
+ def read(size)
762
+ size, data = Rubycdio::read_cd(@cd, size)
763
+ possibly_raise_exception__(size)
764
+ return [size, data]
765
+ end
766
+
767
+ # return [size, data]
768
+ #
769
+ # Reads a number of data sectors (AKA blocks).
770
+ #
771
+ # lsn is sector to read, bytes is the number of bytes.
772
+ # A DeviceError exception may be raised.
773
+ def read_data_blocks(lsn, blocks=1)
774
+ size = Rubycdio::ISO_BLOCKSIZE*blocks
775
+ triple = Rubycdio::read_data_bytes(@cd, lsn,
776
+ Rubycdio::ISO_BLOCKSIZE, size)
777
+ if not triple
778
+ return [-1, nil]
779
+ end
780
+ data, size, drc = triple
781
+ possibly_raise_exception__(drc)
782
+ return [size, data]
783
+ end
784
+
785
+ # return [blocks, data]
786
+ #
787
+ # Reads a number of sectors (AKA blocks).
788
+ #
789
+ # lsn is sector to read, bytes is the number of bytes.
790
+ #
791
+ # If read_mode is Rubycdio::MODE_AUDIO, the return buffer size will be
792
+ # truncated to multiple of Rubycdio::CDIO_FRAMESIZE_RAW i_blocks bytes.
793
+ #
794
+ # If read_mode is Rubycdio::MODE_DATA, buffer will be truncated to a
795
+ # multiple of Rubycdio::ISO_BLOCKSIZE, Rubycdio::M1RAW_SECTOR_SIZE or
796
+ # Rubycdio::M2F2_SECTOR_SIZE bytes depending on what mode the data is in.
797
+ #
798
+ # If read_mode is Rubycdio::MODE_M2F1, buffer will be truncated to a
799
+ # multiple of Rubycdio::M2RAW_SECTOR_SIZE bytes.
800
+ #
801
+ # If read_mode is Rubycdio::MODE_M2F2, the return buffer size will be
802
+ # truncated to a multiple of Rubycdio::CD_FRAMESIZE bytes.
803
+ #
804
+ # The number of bytes read and the data is returned.
805
+ # A DeviceError exception may be raised.
806
+ def read_sectors(lsn, read_mode, blocks=1)
807
+ begin
808
+ blocksize = read_mode2blocksize()[read_mode]
809
+ size = blocks * blocksize
810
+ rescue
811
+ return [-1, nil]
812
+ end
813
+ triple = Rubycdio::read_sectors(@cd, lsn, read_mode, size)
814
+ if not triple
815
+ return [-1, nil]
816
+ end
817
+ data, size, drc = triple
818
+ possibly_raise_exception__(drc)
819
+ blocks = size / blocksize
820
+ return [blocks, data]
821
+ end
822
+
823
+ # Set the blocksize for subsequent reads.
824
+ # An exception is thrown on error.
825
+ def blocksize=(blocksize)
826
+ drc = Rubycdio::set_blocksize(@cd, blocksize)
827
+ possibly_raise_exception__(drc)
828
+ end
829
+
830
+ # Set the drive speed. An exception is thrown on error.
831
+ def speed=(speed)
832
+ drc = Rubycdio::set_speed(@cd, speed)
833
+ possibly_raise_exception__(drc)
834
+ end
835
+ end # Device
836
+
837
+ # = CD Input and control track class
838
+ #
839
+ # == SYNOPSIS
840
+ #
841
+ # require "cdio"
842
+ # d = Device.new("/dev/cdrom")
843
+ # t = d.first_track()
844
+ # first_track = t.track
845
+ # num_tracks = d.num_tracks()
846
+ # last_track = first_track+num_tracks-1
847
+ # for i in first_track .. last_track
848
+ # t = d.track(i)
849
+ # puts "%3d: %06u %-6s %s" % [t.track, t.lsn(), t.msf(), t.format()]
850
+ # end
851
+ # puts "%3X: %06u leadout" % [Rubycdio::CDROM_LEADOUT_TRACK, d.disc_last_lsn()]
852
+ #
853
+ class Track
854
+
855
+ attr_accessor :track
856
+
857
+ def initialize(device, track_num)
858
+
859
+ if track_num.class != Fixnum
860
+ raise TrackError('track number parameter is not an integer')
861
+ end
862
+ @track = track_num
863
+
864
+ # See if the device parameter is a string or
865
+ # a device object.
866
+ if device.class == String
867
+ @device = Device.new(device)
868
+ else
869
+ @device = device
870
+ end
871
+ end
872
+
873
+ # Returns: Fixnum
874
+ #
875
+ # Return number of channels in track: 2 or 4.
876
+ # Not meaningful if track is not an audio track.
877
+ # An exception can be raised on error.
878
+ def audio_channels()
879
+ channels = Rubycdio::get_track_channels(@device, @track)
880
+ if -2 == channels
881
+ raise DriverUnsupportedError
882
+ elsif -1 == channels
883
+ raise TrackError
884
+ else
885
+ return channels
886
+ end
887
+ end
888
+
889
+ # Returns: bool
890
+ #
891
+ # Return copy protection status on a track. Is this meaningful
892
+ # not an audio track?
893
+ def copy_permit?()
894
+ return Rubycdio::track_copy_permit?(@device, @track)
895
+ end
896
+
897
+ # Returns: format (String)
898
+ #
899
+ # Get the format (e.g. 'audio', 'mode2', 'mode1') of track.
900
+ def format()
901
+ return Rubycdio::get_track_format(@device, @track)
902
+ end
903
+
904
+ # Returns: Fixnum (lsn)
905
+ #
906
+ # Return the ending LSN for a track.
907
+ # A TrackError or IOError exception may be raised on error.
908
+ def last_lsn()
909
+ lsn = Rubycdio::get_track_last_lsn(@device, @track)
910
+ if lsn == Rubycdio::INVALID_LSN
911
+ raise TrackError('Invalid LSN returned')
912
+ end
913
+ return lsn
914
+ end
915
+
916
+ # Returns: Fixnum (lba)
917
+ #
918
+ # Return the starting LBA for a track
919
+ # A TrackError exception is raised on error.
920
+ def lba()
921
+ lba = Rubycdio::get_track_lba(@device, @track)
922
+ if lba == Rubycdio::INVALID_LBA
923
+ raise TrackError('Invalid LBA returned')
924
+ end
925
+ return lba
926
+ end
927
+
928
+ # Returns: Fixnum (lsn)
929
+ #
930
+ # Return the starting LSN for a track
931
+ # A TrackError exception is raised on error.
932
+ def lsn()
933
+ lsn = Rubycdio::get_track_lsn(@device, @track)
934
+ if lsn == Rubycdio::INVALID_LSN:
935
+ raise TrackError('Invalid LSN returned')
936
+ end
937
+ return lsn
938
+ end
939
+
940
+ # Returns: String
941
+ #
942
+ # Return the starting MSF (minutes/secs/frames) for track number track.
943
+ # Track numbers usually start at something greater than 0, usually 1.
944
+ #
945
+ # Returns string of the form <i>mm:ss:ff</i> if all good, or string nil on
946
+ # error.
947
+ def msf()
948
+ return Rubycdio::get_track_msf(@device, @track)
949
+ end
950
+
951
+ # Returns: String
952
+ #
953
+ # Get linear preemphasis status on an audio track.
954
+ # This is not meaningful if not an audio track?
955
+ # A TrackError exception is raised on error.
956
+ def preemphasis()
957
+ rc = Rubycdio::get_track_preemphasis(@device, @track)
958
+ if rc == Rubycdio::TRACK_FLAG_FALSE:
959
+ return 'none'
960
+ elsif rc == Rubycdio::TRACK_FLAG_TRUE:
961
+ return 'preemphasis'
962
+ elsif rc == Rubycdio::TRACK_FLAG_UNKNOWN:
963
+ return 'unknown'
964
+ else
965
+ raise TrackError('Invalid return value %d' % d)
966
+ end
967
+ end
968
+
969
+ # Returns: Fixnum
970
+ #
971
+ # Get the number of sectors between this track an the next. This
972
+ # includes any pregap sectors before the start of the next track.
973
+ # Track numbers usually start at something
974
+ # greater than 0, usually 1.
975
+ #
976
+ # A TrackError exception is raised on error.
977
+ def sec_count()
978
+ sec_count = Rubycdio::get_track_sec_count(@device, @track)
979
+ if sec_count == 0
980
+ raise TrackError
981
+ end
982
+ return sec_count
983
+ end
984
+
985
+ # Return true if we have XA data (green, mode2 form1) or
986
+ # XA data (green, mode2 form2). That is track begins:
987
+ # sync - header - subheader
988
+ # 12 4 - 8
989
+ def green?()
990
+ return Rubycdio::track_green?(@device, @track)
991
+ end
992
+
993
+ end # class Track
994
+
995
+ end # Cdio
996
+ include Cdio
997
+ #
998
+ # Local variables:
999
+ # mode: Ruby
1000
+ # End: