= CD-ROM
* ((<CD-ROM outline>))
* ((<SDL::CD>))
* ((<CD-ROM methods>))
  * ((<SDL::CD.num_drives>)) -- Returns the number of CD-ROM drives on the system.
  * ((<SDL::CD.index_name>)) -- Returns a human-readable, system-dependent identifier for the CD-ROM.
  * ((<SDL::CD.open>)) -- Opens a CD-ROM drive for access.
  * ((<SDL::CD#status>)) -- Returns the current status of the given drive.
  * ((<SDL::CD#play>)) -- Play a CD
  * ((<SDL::CD#play_tracks>)) -- Play the given CD track(s)
  * ((<SDL::CD#pause>)) -- Pauses a CDROM
  * ((<SDL::CD#resume>)) -- Resumes a CDROM
  * ((<SDL::CD#stop>)) -- Stops a CDROM
  * ((<SDL::CD#eject>)) -- Ejects a CDROM
  * ((<SDL::CD#num_tracks>)) -- Gets number of tracks on the CD.
  * ((<SDL::CD#current_track>)) -- Gets current track.
  * ((<SDL::CD#current_frame>)) -- Gets current frame offset within the track
  * ((<SDL::CD#track_type>)) -- Gets track type.
  * ((<SDL::CD#track_length>)) -- Gets length of track.
  * ((<SDL::CD#in_drive?>)) -- Check disc in drive
  * ((<SDL::CD.frames_to_msf>)) -- Convert frames into minitus/seconds/frames
  * ((<SDL::CD.msf_to_frames>)) -- Convert minitus/seconds/frames into frames
  * ((<SDL::CD#close>)) -- Closes a CD handle
  * ((<SDL::CD#closed?>)) -- Returns whether CD is closed

== CD-ROM outline
SDL supports audio control of up to 32 local CD-ROM drives at once.

You use this API to perform all the basic functions of a CD player, including
listing the tracks, playing, stopping, and ejecting the CD-ROM. (Currently,
multi-changer CD drives are not supported.)

Before you call any of the SDL CD-ROM functions, you must first call
((<SDL.init>))(SDL::INIT_CDROM),
which scans the system for CD-ROM drives, and sets the program
up for audio control.

After you have initialized the library, you can find out how many drives are
available using the ((<SDL::CD.num_drives>)). The first drive listed is the
system default CD-ROM drive. After you have chosen a drive, and have opened it
with ((<SDL::CD.open>)), you can check the status and start playing if there's a CD in
the drive.

A CD-ROM is organized into one or more tracks, each consisting of a certain number
of "frames". Each frame is ~2K in size, and at normal playing speed,
a CD plays 75(SDL::CD::FPS)
frames per second. SDL works with the number of frames on a CD, but this can
easily be converted to the more familiar minutes/seconds format by using
((<SDL::CD.frames_to_msf>)).

== SDL::CD
This class represents opened CDROM device and stores information on the
layout of the tracks on the disc.

== CD-ROM methods

--- SDL::CD.num_drives
--- SDL::CD.numDrives

    Returns the number of CD-ROM drives on the system.

    * See Also
      
      ((<SDL::CD.open>))

--- SDL::CD.index_name(drive)
--- SDL::CD.indexName(drive)

    Returns a human-readable, system-dependent identifier for the CD-ROM. ((|drive|))
    is the index of the drive.
    Drive indices start to 0 and end at ((<SDL::CD.num_drives>))-1.
    
    Examples of return strings.
    * "/dev/cdrom"
    * "E:"
    * "/dev/disk/ide/1/master"

    * See Also
      
      ((<SDL::CD.num_drives>))

--- SDL::CD.open(drive)

    Opens a CD-ROM drive for access. It returns ((<SDL::CD>)) object on success.
    
    Drives are numbered starting with 0. Drive 0 is the system default CD-ROM.

    Raise ((<SDL::Error>)) if the drive was invalid or busy.


    EXAMPLE
      SDL.init SDL::INIT_CDROM
      
      # Check for CD drives
      if SDL::CD.num_drives == 0
        # None found
        STDERR.print "No CDROM devices available\n"
        exit 255
      end
      
      begin
        # Open the default drive
        cdrom = SDL::CD.open(0)
      rescue SDL::Error
        STDERR.puts "Couldn't open drive"
        exit 255
      end
      
      # Print volume info
      printf "Name: %s\n", SDL::CD.index_name(0)
      printf "Tracks: %d\n", cdrom.num_tracks
      num_tracks.times do |cur_track|
        min, sec, frame = SDL::CD.frames_to_msf(cdrom.track_length(cur_track))
        printf "\tTrack %d: Length %d:%d\n", cur_track, min, sec
      end

--- SDL::CD#status

    This method returns the current status of the given drive. Status is described
    like so:
    * SDL::CD::TRAYEMPTY
    * SDL::CD::STOPPED
    * SDL::CD::PLAYING
    * SDL::CD::PAUSED
    * SDL::CD::ERROR
    
    If the drive has a CD in it,
    ((<SDL.current_track>)), ((<SDL.current_frame>)), ((<SDL.num_tracks>)), ((<SDL.track_type>)),
    and ((<SDL.track_length>)) are updated.


    EXAMPLE
      def play_track(track)
        raise "not cd in drive" unless $cdrom.in_drive?
      
        # clamp to the actual number of tracks on the CD
        track = $cdrom.num_tracks-1 if track >= $cdrom.num_tracks
        $cdrom.play_tracks(track, 0, 1, 0)
      end

--- SDL::CD#play(start, length)

    Plays the given cdrom, starting a frame ((|start|)) for length ((|frames|)).

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::CD#play_tracks>))

--- SDL::CD#play_tracks(start_track, start_frame, ntracks, nframes)

    This method plays the given CD starting at track ((|start_track|)), for ((|ntracks|))
    tracks.
    
    ((|start_frame|)) is the frame offset, from the beginning of the ((|start_track|)),
    at which to start. $nframes] is the frame offset, from the beginning
    of the last track
    (((|start_track|))+((|ntracks|))), at which to end playing.
    
    THis methods should only be called after calling ((<SDL::CD#status>)) to get track
    information about the CD.

    Raises ((<SDL::Error>)) on failure

    EXAMPLE
      # assuming cdrom is a previously opened device
      # Play the entire CD
      if cdrom.in_drive?
        cdrom.play_tracks 0, 0, 0, 0
      end
      # Play the first track
      if cdrom.in_drive?
        cdrom.play_tracks 0, 0, 1, 0
      end
      # 2 Play first 15 seconds of the 2nd track
      if cdrom.in_drive?
        cdrom.play_tracks 1, 0, 0, SDL::CD::FPS*15
      end

    * NOTES

      Data tracks are ignored.

    * See Also
      
      ((<SDL::CD#play>)), ((<SDL::CD#status>))

--- SDL::CD#pause

    Pauses play on the given cdrom.

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::CD#play>)), ((<SDL::CD#resume>))

--- SDL::CD#resume

    Resumes play on the given cdrom.

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::CD#play>)), ((<SDL::CD#pause>))

--- SDL::CD#stop

    Stops play on the given cdrom.

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::CD#play>))

--- SDL::CD#eject

    Ejects the given cdrom.

    Raises ((<SDL::Error>)) on failure
--- SDL::CD#num_tracks
--- SDL::CD#numTracks

    Returns the number of tracks on the given cdrom.
    ((<SDL::CD#status>)) updates this value.

    * See Also
      
      ((<SDL::CD#status>))

--- SDL::CD#current_track
--- SDL::CD#currentTrack

    Returns the currently playing track.
    ((<SDL::CD#status>)) updates this value.

    * See Also
      
      ((<SDL::CD#status>))

--- SDL::CD#current_frame
--- SDL::CD#currentFrame

    Returns the current frame offset with the playing track.
    ((<SDL::CD#status>)) updates this value.

    * See Also
      
      ((<SDL::CD#status>))

--- SDL::CD#track_type(track)
--- SDL::CD#trackType(track)

    Returns the track type in ((|track|)).
    SDL::CD::AUDIO_TRACK or SDL::CD::DATA_TRACK is returned.

--- SDL::CD#track_length(track)
--- SDL::CD#trackLength(track)

    Returns length, in frame, of ((|track|)).

--- SDL::CD#in_drive?

    Returns true if drive is not empty, otherwise returns false.

    * See Also
      
      ((<SDL::CD#status>))

--- SDL::CD.frames_to_msf(frames)
--- SDL::CD.framesToMSF(frames)

    Converts frames into minitus/seconds/frames, and returns an array like
    [min, sec, frames].

    * See Also
      
      ((<SDL::CD.msf_to_frames>))

--- SDL::CD.msf_to_frames(min, sec, frames)
--- SDL::CD.MSFToFrames(min, sec, frames)

    Convert minitus/seconds/frames into frames and returns frames.

    * See Also
      
      ((<SDL::CD.frames_to_msf>))

--- SDL::CD#close

    Closes ((|self|)).

    * See Also
      
      ((<SDL::CD.open>)), ((<SDL::CD#closed?>))

--- SDL::CD#closed?

    Returns whether CD handle is closed by
    ((<SDL::CD#close>))

    * See Also
      
      ((<SDL::CD#close>))

