-
# Copyright (C) 2013-2017, 2019 Philipp Wolfer
-
#
-
# This program is free software: you can redistribute it and/or modify
-
# it under the terms of the GNU Lesser General Public License as published by
-
# the Free Software Foundation, either version 3 of the License, or
-
# (at your option) any later version.
-
#
-
# This program is distributed in the hope that it will be useful,
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
# GNU Lesser General Public License for more details.
-
#
-
# You should have received a copy of the GNU Lesser General Public License
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
1
require 'discid/lib'
-
1
require 'discid/disc'
-
1
require 'discid/version'
-
-
# 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 http://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)
-
1
module DiscId
-
-
# 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]
-
1
def self.read(device = nil, *features)
-
3
disc = Disc.new
-
3
disc.read device, *features
-
return disc
-
end
-
-
# 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]
-
1
def self.put(first_track, sectors, offsets)
-
10
disc = Disc.new
-
10
disc.put first_track, sectors, offsets
-
7
return disc
-
end
-
-
# 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]
-
1
def self.parse(toc)
-
8
if toc.nil? || toc.empty?
-
2
raise DiscError, "Invalid TOC #{toc.inspect}"
-
end
-
begin
-
6
parts = toc.split(' ')
-
6
first_track = Integer(parts[0])
-
6
sectors = Integer(parts[2])
-
29
offsets = parts[3..-1].map{|i| Integer(i)}
-
rescue ArgumentError, TypeError => e
-
2
raise DiscError, e
-
end
-
4
return self.put(first_track, sectors, offsets)
-
end
-
-
# Return the name of the default disc drive for this operating system.
-
#
-
# @return [String] An operating system dependent device identifier
-
1
def self.default_device
-
1
Lib.default_device
-
end
-
-
# 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.
-
1
def self.has_feature?(feature)
-
4
feature = feature.to_sym if feature.respond_to? :to_sym
-
4
return self.feature_list.include? feature
-
end
-
-
# 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>]
-
1
def self.feature_list
-
20
return Lib::Features.symbols.select {|f| Lib.has_feature(f) == 1}
-
end
-
-
# 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
-
1
def self.sectors_to_seconds(sectors)
-
147
return (sectors.to_f / 75).truncate
-
end
-
-
# 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".
-
1
LIBDISCID_VERSION = Lib.get_version_string
-
-
end