module DiscId

The DiscId module allows calculating DiscIDs (MusicBrainz and freedb) for Audio CDs. Additionally the library can extract the MCN/UPC/EAN and the ISRCs from disc.

The main interface for using this module are the {read} and {put} methods which both return an instance of {Disc}. {read} allows you to read the data from an actual CD drive while {put} allows you to calculate the DiscID for a previously read CD TOC.

Depending on the version of libdiscid and the operating system used additional features like reading the MCN or ISRCs from the disc might be available. You can check for supported features with {has_feature?}.

@see musicbrainz.org/doc/libdiscid#Feature_Matrix

@example Read the TOC, MCN and ISRCs

require 'discid'

device = "/dev/cdrom"
disc = DiscId.read(device, :mcn, :isrc)

# Print information about the disc:
puts "DiscID      : #{disc.id}"
puts "FreeDB ID   : #{disc.freedb_id}"
puts "Total length: #{disc.seconds} seconds"
puts "MCN         : #{disc.mcn}"

# Print information about individual tracks:
disc.tracks do |track|
  puts "Track ##{track.number}"
  puts "  Length: %02d:%02d (%i sectors)" %
      [track.seconds / 60, track.seconds % 60, track.sectors]
  puts "  ISRC  : %s" % track.isrc
end

@example Get the DiscID for an existing TOC

require 'discid'

first_track = 1
sectors = 82255
offsets = [150, 16157, 35932, 57527]
disc = DiscId.put(first_track, sectors, offsets)
puts disc.id # Output: E5VLOkhodzhvsMlK8LSNVioYOgY-

@example Check for supported MCN feature

disc = DiscId.read(nil, :mcn)
puts "MCN: #{disc.mcn}" if DiscId.has_feature?(:mcn)

Constants

LIBDISCID_VERSION

The libdiscid version.

@note This will only give meaningful results for libdiscid 0.4.0

and higher. For lower versions this constant  will always have
the value "libdiscid < 0.4.0".
VERSION

The version of ruby-discid.

Public Class Methods

default_device() click to toggle source

Return the name of the default disc drive for this operating system.

@return [String] An operating system dependent device identifier

# File lib/discid.rb, line 149
def self.default_device
  Lib.default_device
end
feature_list() click to toggle source

A list of features supported by the current platform.

Currently the following features are available:

  • :read

  • :mcn

  • :isrc

@note libdiscid >= 0.5.0 required. Older versions will return only [:read].

@return [Array<Symbol>]

# File lib/discid.rb, line 178
def self.feature_list
  return Lib::Features.symbols.select {|f| Lib.has_feature(f) == 1}
end
has_feature?(feature) click to toggle source

Check if a certain feature is implemented on the current platform.

You can obtain a list of supported features with {feature_list}.

@note libdiscid >= 0.5.0 required. Older versions will return `true`

for `:read` and `false` for anything else.

@param feature [:read, :mcn, :isrc] @return [Boolean] True if the feature is implemented and false if not.

# File lib/discid.rb, line 162
def self.has_feature?(feature)
  feature = feature.to_sym if feature.respond_to? :to_sym
  return self.feature_list.include? feature
end
parse(toc) click to toggle source

Parses a TOC string and returns a [Disc] instance for it.

This function can be used if you already have a TOC string like e.g. `1 11 242457 150 44942 61305 72755 96360 130485 147315 164275 190702 205412 220437`

@raise [DiscError] The TOC string was invalid and could not be parsed. @param toc [String] A TOC string in the format `1 11 242457 150 44942 61305 72755 96360 130485 147315 164275 190702 205412 220437`. @return [Disc]

# File lib/discid.rb, line 131
def self.parse(toc)
  if toc.nil? || toc.empty?
    raise DiscError, "Invalid TOC #{toc.inspect}"
  end
  begin
    parts = toc.split(' ')
    first_track = Integer(parts[0])
    sectors = Integer(parts[2])
    offsets = parts[3..-1].map{|i| Integer(i)}
  rescue ArgumentError, TypeError => e
    raise DiscError, e
  end
  return self.put(first_track, sectors, offsets)
end
put(first_track, sectors, offsets) click to toggle source

Provides the TOC of a known CD.

This function may be used if the TOC has been read earlier and you want to calculate the disc ID afterwards, without accessing the disc drive.

@raise [DiscError] The TOC could not be set. `Exception#message`contains

error details.

@param first_track [Integer] The number of the first audio track on the

disc (usually one).

@param sectors [Integer] The total number of sectors on the disc. @param offsets [Array] An array with track offsets (sectors) for each track. @return [Disc]

# File lib/discid.rb, line 117
def self.put(first_track, sectors, offsets)
  disc = Disc.new
  disc.put first_track, sectors, offsets
  return disc
end
read(device = nil, *features) click to toggle source

Read the disc in the given CD-ROM/DVD-ROM drive extracting only the TOC and additionally specified features.

This function reads the disc in the drive specified by the given device identifier. If the device is `nil`, the default device, as returned by {default_device}, is used.

This function will always read the TOC, but additional features like `:mcn` and `:isrc` can be set using the features parameter. You can set multiple features.

@example Read only the TOC:

disc = DiscId.read(device)

@example Read the TOC, MCN and ISRCs:

disc = DiscId.read(device, :mcn, :isrc)

@note libdiscid >= 0.5.0 is required for the feature selection to work.

Older versions will allways read MCN and ISRCs when supported. See
{http://musicbrainz.org/doc/libdiscid#Feature_Matrix} for a list of
supported features by version and platform.

@raise [TypeError] `device` can not be converted to a String. @raise [DiscError] Error reading from `device`. `Exception#message` contains

error details.

@param device [String] The device identifier. If set to `nil` {default_device}

will be used.

@param features [:mcn, :isrc] List of features to use.

`:read` is always implied.

@return [Disc]

# File lib/discid.rb, line 99
def self.read(device = nil, *features)
  disc = Disc.new
  disc.read device, *features
  return disc
end
sectors_to_seconds(sectors) click to toggle source

Converts sectors to seconds.

According to the red book standard 75 sectors are one second.

@private @param sectors [Integer] Number of sectors @return [Integer] The seconds

# File lib/discid.rb, line 189
def self.sectors_to_seconds(sectors)
  return (sectors.to_f / 75).truncate
end