mb-discid 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -1
- data/README +15 -1
- data/Rakefile +5 -4
- data/examples/discid.rb +31 -13
- data/ext/mb_discid.c +72 -34
- data/lib/mb-discid.rb +156 -15
- data/test/test_discid.rb +67 -2
- metadata +5 -5
data/CHANGES
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 0.1.3 (2009-11-19)
|
4
|
+
* Added singleton method +sectors_to_seconds+ to convert sectors into seconds
|
5
|
+
* Added method +seconds+ to retrieve disc length in seconds
|
6
|
+
* Added method +track_info+ for accessing more detailed information about tracks
|
7
|
+
* Fixed building with Ruby 1.9 (Mihaly Csomay)
|
8
|
+
|
3
9
|
== 0.1.2 (2007-07-04)
|
4
10
|
* Support the method +put+ to set the TOC information directly instead of
|
5
11
|
reading it from a device.
|
@@ -17,4 +23,4 @@
|
|
17
23
|
== 0.1.0 (2007-06-02)
|
18
24
|
* Initial release
|
19
25
|
|
20
|
-
$Id: CHANGES
|
26
|
+
$Id: CHANGES 298 2009-11-19 09:26:45Z phw $
|
data/README
CHANGED
@@ -5,6 +5,10 @@ MB-DiscID provides Ruby bindings for the MusicBrainz DiscID library libdiscid.
|
|
5
5
|
It allows you to calculate MusicBrainz DiscIDs from audio CDs which you can use
|
6
6
|
to find the release entry for your CD in the MusicBrainz database.
|
7
7
|
|
8
|
+
== Requirements
|
9
|
+
* Ruby >= 1.8.6
|
10
|
+
* libdiscid >= 0.1.0
|
11
|
+
|
8
12
|
== Installation
|
9
13
|
Before installing rdiscid make sure you have libdiscid installed. See
|
10
14
|
http://musicbrainz.org/doc/libdiscid for more information on how to do this.
|
@@ -32,9 +36,19 @@ install it follow the instructions below:
|
|
32
36
|
See the documentation of MusicBrainz::DiscID or the example files in the
|
33
37
|
+examples+ directory for usage information.
|
34
38
|
|
39
|
+
== Contact
|
40
|
+
MB-DiscID is part of the RBrainz project which provides a library to query
|
41
|
+
the MusicBrainz XML web service. For more information about MB-DiscID or
|
42
|
+
RBrainz visit http://rbrainz.rubyforge.org.
|
43
|
+
|
44
|
+
If you have any questions or suggestions regarding MB-DiscID please write to
|
45
|
+
the rbrainz-user mailinglist[http://rubyforge.org/mail/?group_id=3677].
|
46
|
+
If you find bugs or if you have any feature requests please use the
|
47
|
+
RBrainz bug tracker[http://rubyforge.org/tracker/?group_id=3677].
|
48
|
+
|
35
49
|
== License
|
36
50
|
MB-DiscID is Copyright (c) 2007 Philipp Wolfer.
|
37
51
|
It is free softare distributed under a BSD style license. See
|
38
52
|
LICENSE[link:files/LICENSE.html] for details.
|
39
53
|
|
40
|
-
$Id: README
|
54
|
+
$Id: README 298 2009-11-19 09:26:45Z phw $
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: Rakefile
|
1
|
+
# $Id: Rakefile 296 2009-11-18 22:09:36Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -17,7 +17,7 @@ end
|
|
17
17
|
# Packaging tasks: -------------------------------------------------------
|
18
18
|
|
19
19
|
PKG_NAME = 'mb-discid'
|
20
|
-
PKG_VERSION = '0.1.
|
20
|
+
PKG_VERSION = '0.1.3'
|
21
21
|
PKG_SUMMARY = 'Ruby bindings for libdiscid.'
|
22
22
|
PKG_AUTHOR = 'Philipp Wolfer'
|
23
23
|
PKG_EMAIL = 'phw@rubyforge.org'
|
@@ -28,7 +28,7 @@ PKG_DESCRIPTION = <<EOF
|
|
28
28
|
EOF
|
29
29
|
PKG_FILES = FileList[
|
30
30
|
'Rakefile', 'LICENSE', 'README', 'CHANGES',
|
31
|
-
'examples
|
31
|
+
'examples/**/*.rb',
|
32
32
|
'ext/**/*.{c,rb}',
|
33
33
|
'lib/**/*.rb',
|
34
34
|
'test/**/*.rb'
|
@@ -48,6 +48,7 @@ spec = Gem::Specification.new do |spec|
|
|
48
48
|
spec.platform = Gem::Platform::RUBY
|
49
49
|
spec.files = PKG_FILES
|
50
50
|
spec.extensions << 'ext/extconf.rb'
|
51
|
+
spec.required_ruby_version = ">= 1.8.6"
|
51
52
|
end
|
52
53
|
spec.requirements << 'libdiscid (http://musicbrainz.org/doc/libdiscid)'
|
53
54
|
spec.require_paths = ['lib', 'ext']
|
@@ -130,7 +131,7 @@ Rake::RDocTask.new do |rdoc|
|
|
130
131
|
rdoc.title = "MB-DiscID %s" % PKG_VERSION
|
131
132
|
rdoc.main = 'README'
|
132
133
|
rdoc.rdoc_dir = 'doc/api'
|
133
|
-
rdoc.rdoc_files.include('
|
134
|
+
rdoc.rdoc_files.include('ext/**/*.c', 'lib/**/*.rb', PKG_EXTRA_RDOC_FILES)
|
134
135
|
rdoc.options << '--inline-source' << '--line-numbers' #<< '--diagram'
|
135
136
|
end
|
136
137
|
|
data/examples/discid.rb
CHANGED
@@ -9,31 +9,49 @@
|
|
9
9
|
# Example:
|
10
10
|
# ./discid.rb /dev/dvd
|
11
11
|
#
|
12
|
-
# $Id: discid.rb
|
12
|
+
# $Id: discid.rb 201 2008-02-13 14:59:48Z phw $
|
13
13
|
|
14
14
|
require 'mb-discid'
|
15
15
|
|
16
16
|
# Read the device name from the command line or use the default.
|
17
17
|
device = $*[0] ? $*[0] : MusicBrainz::DiscID.default_device
|
18
18
|
|
19
|
+
# Create a new DiscID object and read the disc information.
|
20
|
+
# In case of errors exit the application.
|
19
21
|
puts "Reading TOC from device '#{device}'."
|
22
|
+
begin
|
23
|
+
disc = MusicBrainz::DiscID.new
|
24
|
+
disc.read(device)
|
25
|
+
|
26
|
+
# Instead of reading from a device we could set the TOC directly:
|
27
|
+
# disc.put(1, 82255, [150, 16157, 35932, 57527])
|
28
|
+
rescue Exception => e
|
29
|
+
puts e
|
30
|
+
exit(1)
|
31
|
+
end
|
20
32
|
|
21
|
-
|
22
|
-
disc.read(device)
|
23
|
-
|
33
|
+
# Print information about the disc:
|
24
34
|
print <<EOF
|
25
35
|
|
26
|
-
DiscID
|
27
|
-
FreeDB ID
|
28
|
-
First track: #{disc.first_track_num}
|
29
|
-
Last track
|
30
|
-
|
36
|
+
DiscID : #{disc.id}
|
37
|
+
FreeDB ID : #{disc.freedb_id}
|
38
|
+
First track : #{disc.first_track_num}
|
39
|
+
Last track : #{disc.last_track_num}
|
40
|
+
Total length: #{disc.seconds} seconds
|
41
|
+
Sectors : #{disc.sectors}
|
31
42
|
EOF
|
32
43
|
|
33
|
-
|
34
|
-
disc.
|
35
|
-
puts "Track
|
36
|
-
|
44
|
+
# Print information about individual tracks:
|
45
|
+
disc.track_details do |track_info|
|
46
|
+
puts "Track ##{track_info.number}"
|
47
|
+
puts " Length: %02d:%02d (%i sectors)" %
|
48
|
+
[track_info.seconds / 60, track_info.seconds % 60, track_info.sectors]
|
49
|
+
puts " Start : %02d:%02d (sector %i)" %
|
50
|
+
[track_info.start_time / 60, track_info.start_time % 60, track_info.start_sector]
|
51
|
+
puts " End : %02d:%02d (sector %i)" %
|
52
|
+
[track_info.end_time / 60, track_info.end_time % 60, track_info.end_sector]
|
37
53
|
end
|
38
54
|
|
55
|
+
# Print a submission URL that can be used to submit
|
56
|
+
# the disc ID to MusicBrainz.org.
|
39
57
|
puts "\nSubmit via #{disc.submission_url}"
|
data/ext/mb_discid.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* $Id: mb_discid.c
|
2
|
+
* $Id: mb_discid.c 297 2009-11-18 22:18:10Z phw $
|
3
3
|
*
|
4
4
|
* Ruby bindings for libdiscid. See http://musicbrainz.org/doc/libdiscid
|
5
5
|
* for more information on libdiscid and MusicBrainz.
|
@@ -24,6 +24,9 @@ static VALUE mMusicBrainz;
|
|
24
24
|
static VALUE cDiscID;
|
25
25
|
|
26
26
|
/**
|
27
|
+
* call-seq:
|
28
|
+
* id() -> string or nil
|
29
|
+
*
|
27
30
|
* Returns the DiscID as a string.
|
28
31
|
*
|
29
32
|
* Returns +nil+ if no ID was yet read.
|
@@ -42,6 +45,9 @@ static VALUE mb_discid_id(VALUE self)
|
|
42
45
|
}
|
43
46
|
|
44
47
|
/**
|
48
|
+
* call-seq:
|
49
|
+
* submission_url() -> string or nil
|
50
|
+
*
|
45
51
|
* Returns a submission URL for the DiscID as a string.
|
46
52
|
*
|
47
53
|
* Returns +nil+ if no ID was yet read.
|
@@ -60,7 +66,10 @@ static VALUE mb_discid_submission_url(VALUE self)
|
|
60
66
|
}
|
61
67
|
|
62
68
|
/**
|
63
|
-
*
|
69
|
+
* call-seq:
|
70
|
+
* freedb_id() -> string or nil
|
71
|
+
*
|
72
|
+
* Returns a FreeDB DiscID as a string.
|
64
73
|
*
|
65
74
|
* Returns +nil+ if no ID was yet read.
|
66
75
|
*/
|
@@ -78,6 +87,9 @@ static VALUE mb_discid_freedb_id(VALUE self)
|
|
78
87
|
}
|
79
88
|
|
80
89
|
/**
|
90
|
+
* call-seq:
|
91
|
+
* first_track_num() -> int or nil
|
92
|
+
*
|
81
93
|
* Return the number of the first track on this disc (usually 1).
|
82
94
|
*
|
83
95
|
* Returns +nil+ if no ID was yet read.
|
@@ -96,6 +108,9 @@ static VALUE mb_discid_first_track_num(VALUE self)
|
|
96
108
|
}
|
97
109
|
|
98
110
|
/**
|
111
|
+
* call-seq:
|
112
|
+
* last_track_num() -> int or nil
|
113
|
+
*
|
99
114
|
* Return the number of the last track on this disc.
|
100
115
|
*
|
101
116
|
* Returns +nil+ if no ID was yet read.
|
@@ -114,6 +129,9 @@ static VALUE mb_discid_last_track_num(VALUE self)
|
|
114
129
|
}
|
115
130
|
|
116
131
|
/**
|
132
|
+
* call-seq:
|
133
|
+
* sectors() -> int or nil
|
134
|
+
*
|
117
135
|
* Return the length of the disc in sectors.
|
118
136
|
*
|
119
137
|
* Returns +nil+ if no ID was yet read.
|
@@ -132,6 +150,10 @@ static VALUE mb_discid_sectors(VALUE self)
|
|
132
150
|
}
|
133
151
|
|
134
152
|
/**
|
153
|
+
* call-seq:
|
154
|
+
* tracks() -> array
|
155
|
+
* tracks() {|offset, length| block }
|
156
|
+
*
|
135
157
|
* Returns an array of <tt>[offset, length]</tt> tuples for each track.
|
136
158
|
*
|
137
159
|
* Offset and length are both integer values representing sectors.
|
@@ -140,6 +162,9 @@ static VALUE mb_discid_sectors(VALUE self)
|
|
140
162
|
*
|
141
163
|
* Returns always +nil+ if no ID was yet read. The block won't be called in
|
142
164
|
* this case.
|
165
|
+
*
|
166
|
+
* You may want to use the method track_details instead of this method to
|
167
|
+
* retrieve more detailed information about the tracks.
|
143
168
|
*/
|
144
169
|
static VALUE mb_discid_tracks(VALUE self)
|
145
170
|
{
|
@@ -177,10 +202,15 @@ static VALUE mb_discid_tracks(VALUE self)
|
|
177
202
|
}
|
178
203
|
|
179
204
|
/**
|
205
|
+
* call-seq:
|
206
|
+
* read(device=nil)
|
207
|
+
*
|
180
208
|
* Read the disc ID from the given device.
|
181
209
|
*
|
182
210
|
* If no device is given the default device of the platform will be used.
|
183
|
-
* Throws an
|
211
|
+
* Throws an _Exception_ if the CD's TOC can not be read.
|
212
|
+
*
|
213
|
+
* Raises:: ArgumentError, TypeError, Exception
|
184
214
|
*/
|
185
215
|
static VALUE mb_discid_read(int argc, VALUE *argv, VALUE self)
|
186
216
|
{
|
@@ -190,23 +220,18 @@ static VALUE mb_discid_read(int argc, VALUE *argv, VALUE self)
|
|
190
220
|
|
191
221
|
Data_Get_Struct(self, DiscId, disc);
|
192
222
|
|
193
|
-
/* Check the number of arguments */
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
else
|
198
|
-
|
199
|
-
if(rb_respond_to(argv[0], rb_intern("to_s")))
|
200
|
-
device = rb_funcall(argv[0], rb_intern("to_s"), 0, 0);
|
201
|
-
else
|
202
|
-
rb_raise(rb_eTypeError, "wrong argument type (expected String)");
|
203
|
-
}
|
223
|
+
/* Check the number and types of arguments */
|
224
|
+
rb_scan_args(argc, argv, "1", &device);
|
225
|
+
if(rb_respond_to(device, rb_intern("to_s")))
|
226
|
+
device = rb_funcall(device, rb_intern("to_s"), 0, 0);
|
227
|
+
else
|
228
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected String)");
|
204
229
|
|
205
230
|
/* Use the default device if none was given. */
|
206
|
-
if (
|
231
|
+
if (device == Qnil)
|
207
232
|
cdevice = discid_get_default_device();
|
208
233
|
else
|
209
|
-
cdevice =
|
234
|
+
cdevice = StringValuePtr(device);
|
210
235
|
|
211
236
|
/* Mark the disc id as unread in case something goes wrong. */
|
212
237
|
rb_iv_set(self, "@read", Qfalse);
|
@@ -222,22 +247,27 @@ static VALUE mb_discid_read(int argc, VALUE *argv, VALUE self)
|
|
222
247
|
}
|
223
248
|
|
224
249
|
/**
|
250
|
+
* call-seq:
|
251
|
+
* put(first_track, sectors, offsets)
|
252
|
+
*
|
225
253
|
* Set the TOC information directly instead of reading it from a device.
|
226
254
|
*
|
227
255
|
* Use this instead of read if the TOC information was already read elsewhere
|
228
256
|
* and you want to recalculate the ID.
|
229
|
-
* Throws an
|
257
|
+
* Throws an _Exception_ if the CD's TOC can not be read.
|
230
258
|
*
|
231
259
|
* <b>Parameters:</b>
|
232
260
|
* [first_track] The number of the first track on the disc (usually 1).
|
233
261
|
* [sectors] The total number of sectors on the disc.
|
234
262
|
* [offsets] Array of all track offsets. The number of tracks must not exceed 99.
|
263
|
+
*
|
264
|
+
* Raises:: Exception
|
235
265
|
*/
|
236
266
|
static VALUE mb_discid_put(VALUE self, VALUE first_track, VALUE sectors,
|
237
267
|
VALUE offsets)
|
238
268
|
{
|
239
269
|
DiscId *disc; /* Pointer to the disc struct */
|
240
|
-
long length =
|
270
|
+
long length = RARRAY_LEN(offsets); /* length of the offsets array */
|
241
271
|
int cfirst = NUM2INT(first_track); /* number of the first track */
|
242
272
|
int clast = length + 1 - cfirst; /* number of the last track */
|
243
273
|
int coffsets[100]; /* C array to hold the offsets */
|
@@ -267,30 +297,38 @@ static VALUE mb_discid_put(VALUE self, VALUE first_track, VALUE sectors,
|
|
267
297
|
}
|
268
298
|
|
269
299
|
/**
|
300
|
+
* call-seq:
|
301
|
+
* MusicBrainz::DiscID.new(device=nil) -> obj
|
302
|
+
*
|
270
303
|
* Construct a new DiscID object.
|
271
304
|
*
|
272
305
|
* As an optional argument the name of the device to read the ID from
|
273
306
|
* may be given. If you don't specify a device here you can later read
|
274
307
|
* the ID with the read method.
|
308
|
+
*
|
309
|
+
* Raises:: ArgumentError, TypeError, Exception
|
275
310
|
*/
|
276
311
|
VALUE mb_discid_new(int argc, VALUE *argv, VALUE class)
|
277
312
|
{
|
278
313
|
DiscId *disc = discid_new();
|
279
314
|
VALUE tdata = Data_Wrap_Struct(class, 0, discid_free, disc);
|
315
|
+
VALUE device = Qnil;
|
280
316
|
rb_obj_call_init(tdata, 0, 0);
|
281
317
|
rb_iv_set(tdata, "@read", Qfalse);
|
282
318
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
rb_funcall(tdata, rb_intern("read"), 1, argv[0]);
|
319
|
+
/* Check the number of arguments */
|
320
|
+
rb_scan_args(argc, argv, "01", &device);
|
321
|
+
|
322
|
+
if (device != Qnil)
|
323
|
+
rb_funcall(tdata, rb_intern("read"), 1, device);
|
289
324
|
|
290
325
|
return tdata;
|
291
326
|
}
|
292
327
|
|
293
328
|
/**
|
329
|
+
* call-seq:
|
330
|
+
* MusicBrainz::DiscID.default_device(device=nil) -> string
|
331
|
+
*
|
294
332
|
* Returns a device string for the default device for this platform.
|
295
333
|
*/
|
296
334
|
VALUE mb_discid_default_device(VALUE class)
|
@@ -304,18 +342,18 @@ VALUE mb_discid_default_device(VALUE class)
|
|
304
342
|
void Init_MB_DiscID()
|
305
343
|
{
|
306
344
|
mMusicBrainz = rb_define_module("MusicBrainz");
|
307
|
-
|
345
|
+
cDiscID = rb_define_class_under(mMusicBrainz, "DiscID", rb_cObject);
|
308
346
|
rb_define_singleton_method(cDiscID, "new", mb_discid_new, -1);
|
309
347
|
rb_define_singleton_method(cDiscID, "default_device",
|
310
348
|
mb_discid_default_device, 0);
|
311
349
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
350
|
+
rb_define_method(cDiscID, "read", mb_discid_read, -1);
|
351
|
+
rb_define_method(cDiscID, "put", mb_discid_put, 3);
|
352
|
+
rb_define_method(cDiscID, "id", mb_discid_id, 0);
|
353
|
+
rb_define_method(cDiscID, "submission_url", mb_discid_submission_url, 0);
|
354
|
+
rb_define_method(cDiscID, "freedb_id", mb_discid_freedb_id, 0);
|
355
|
+
rb_define_method(cDiscID, "first_track_num", mb_discid_first_track_num, 0);
|
356
|
+
rb_define_method(cDiscID, "last_track_num", mb_discid_last_track_num, 0);
|
357
|
+
rb_define_method(cDiscID, "sectors", mb_discid_sectors, 0);
|
358
|
+
rb_define_method(cDiscID, "tracks", mb_discid_tracks, 0);
|
321
359
|
}
|
data/lib/mb-discid.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: mb-discid.rb
|
1
|
+
# $Id: mb-discid.rb 201 2008-02-13 14:59:48Z phw $
|
2
2
|
#
|
3
3
|
# Just a helper file to allow loading the MB-DiscID library with
|
4
4
|
# <tt>require 'mb-discid'</tt>, which is the only recommended way
|
@@ -26,31 +26,45 @@ module MusicBrainz
|
|
26
26
|
#
|
27
27
|
# require 'mb-discid'
|
28
28
|
#
|
29
|
-
# # Create a new DiscID object
|
29
|
+
# # Create a new DiscID object.
|
30
30
|
# disc = MusicBrainz::DiscID.new
|
31
31
|
#
|
32
32
|
# # Read the TOC from the default device.
|
33
33
|
# # An audio CD must be inserted in the drive. An exception will be thrown
|
34
34
|
# # if the CD can't be read.
|
35
|
-
#
|
35
|
+
# begin
|
36
|
+
# disc.read
|
37
|
+
# rescue Exception => e
|
38
|
+
# puts e
|
39
|
+
# exit(1)
|
40
|
+
# end
|
36
41
|
#
|
37
42
|
# # Print information about the disc:
|
38
43
|
# print <<EOF
|
39
|
-
# DiscID
|
40
|
-
# Submit via
|
41
|
-
# FreeDB ID
|
42
|
-
# First track: #{disc.first_track_num}
|
43
|
-
# Last track
|
44
|
-
#
|
44
|
+
# DiscID : #{disc.id}
|
45
|
+
# Submit via : #{disc.submission_url}
|
46
|
+
# FreeDB ID : #{disc.freedb_id}
|
47
|
+
# First track : #{disc.first_track_num}
|
48
|
+
# Last track : #{disc.last_track_num}
|
49
|
+
# Total length: #{disc.seconds} seconds
|
50
|
+
# Sectors : #{disc.sectors}
|
45
51
|
# EOF
|
46
52
|
#
|
47
53
|
# # Print information about individual tracks:
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# puts "
|
51
|
-
#
|
54
|
+
# disc.track_details do |track_info|
|
55
|
+
# puts "Track ##{track_info.number}"
|
56
|
+
# puts " Length: %02d:%02d (%i sectors)" %
|
57
|
+
# [track_info.seconds / 60, track_info.seconds % 60, track_info.sectors]
|
58
|
+
# puts " Start : %02d:%02d (sector %i)" %
|
59
|
+
# [track_info.start_time / 60, track_info.start_time % 60, track_info.start_sector]
|
60
|
+
# puts " End : %02d:%02d (sector %i)" %
|
61
|
+
# [track_info.end_time / 60, track_info.end_time % 60, track_info.end_sector]
|
52
62
|
# end
|
53
63
|
#
|
64
|
+
# # Print a submission URL that can be used to submit
|
65
|
+
# # the disc ID to MusicBrainz.org.
|
66
|
+
# puts "\nSubmit via #{disc.submission_url}"
|
67
|
+
#
|
54
68
|
# === Specifying the device to read from:
|
55
69
|
#
|
56
70
|
# # Create a new DiscID object and read the disc in /dev/dvd:
|
@@ -77,10 +91,137 @@ module MusicBrainz
|
|
77
91
|
# puts disc.id # Should print "T_prJXQSrqbnH8OE.dgOKsHm5Uw-"
|
78
92
|
#
|
79
93
|
class DiscID
|
94
|
+
|
95
|
+
# This class holds information about a single track.
|
96
|
+
#
|
97
|
+
# Currently this includes the following fields:
|
98
|
+
# [number] The number of the track on the disc.
|
99
|
+
# [sectors] Length of the track in sectors.
|
100
|
+
# [start_sector] Start position of the track on the disc in sectors.
|
101
|
+
# [end_sector] End position of the track on the disc in sectors.
|
102
|
+
# [seconds] Length of the track in seconds.
|
103
|
+
# [start_time] Start position of the track on the disc in seconds.
|
104
|
+
# [end_time] End position of the track on the disc in seconds.
|
105
|
+
#
|
106
|
+
# You can access all fields either with directly or with the square bracket
|
107
|
+
# notation:
|
108
|
+
#
|
109
|
+
# track = TrackInfo.new(1, 150, 16007)
|
110
|
+
# puts track.sectors # 16007
|
111
|
+
# puts track[:sectors] # 16007
|
112
|
+
#
|
113
|
+
# See:: DiscID#track_details
|
114
|
+
class TrackInfo
|
115
|
+
|
116
|
+
# The number of the track on the disc.
|
117
|
+
attr_reader :number
|
118
|
+
|
119
|
+
# Length of the track in sectors.
|
120
|
+
attr_reader :sectors
|
121
|
+
|
122
|
+
# Start position of the track on the disc in sectors.
|
123
|
+
attr_reader :start_sector
|
124
|
+
|
125
|
+
# Returns a new TrackInfo.
|
126
|
+
def initialize(number, offset, length)
|
127
|
+
@number = number
|
128
|
+
@start_sector = offset
|
129
|
+
@sectors = length
|
130
|
+
end
|
131
|
+
|
132
|
+
# End position of the track on the disc in sectors.
|
133
|
+
def end_sector
|
134
|
+
start_sector + sectors
|
135
|
+
end
|
136
|
+
|
137
|
+
# Length of the track in seconds.
|
138
|
+
def seconds
|
139
|
+
DiscID.sectors_to_seconds(sectors)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Start position of the track on the disc in seconds.
|
143
|
+
def start_time
|
144
|
+
DiscID.sectors_to_seconds(start_sector)
|
145
|
+
end
|
146
|
+
|
147
|
+
# End position of the track on the disc in seconds.
|
148
|
+
def end_time
|
149
|
+
DiscID.sectors_to_seconds(end_sector)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Allows access to all fields similar to accessing values in a hash.
|
153
|
+
#
|
154
|
+
# Example:
|
155
|
+
# track = TrackInfo.new(1, 150, 16007)
|
156
|
+
# puts track.sectors # 16007
|
157
|
+
# puts track[:sectors] # 16007
|
158
|
+
def [](key)
|
159
|
+
if [:number, :sectors, :start_sector, :end_sector,
|
160
|
+
:seconds, :start_time, :end_time].include?(key.to_sym)
|
161
|
+
method(key).call
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Converts the TrackInfo into a Hash.
|
166
|
+
def to_hash
|
167
|
+
{
|
168
|
+
:sectors => sectors,
|
169
|
+
:start_sector => start_sector,
|
170
|
+
:end_sector => end_sector,
|
171
|
+
:seconds => seconds,
|
172
|
+
:start_time => start_time,
|
173
|
+
:end_time => end_time,
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
80
178
|
|
81
|
-
# DiscID to String conversion. Same as calling the method id
|
179
|
+
# DiscID to String conversion. Same as calling the method id but guaranteed
|
180
|
+
# to return a string.
|
82
181
|
def to_s
|
83
|
-
|
182
|
+
id.to_s
|
183
|
+
end
|
184
|
+
|
185
|
+
# Return the length of the disc in sectors.
|
186
|
+
#
|
187
|
+
# Returns <tt>nil</tt> if no ID was yet read.
|
188
|
+
def seconds
|
189
|
+
DiscID.sectors_to_seconds(sectors) unless @read == false
|
190
|
+
end
|
191
|
+
|
192
|
+
# Returns an array of TrackInfo objects. Each TrackInfo object contains
|
193
|
+
# detailed information about the track.
|
194
|
+
#
|
195
|
+
# If a block is given this method returns <tt>nil</tt> and instead iterates
|
196
|
+
# over the block calling the block with one argument <tt>|track_info|</tt>.
|
197
|
+
#
|
198
|
+
# Returns always <tt>nil</tt> if no ID was yet read. The block won't be
|
199
|
+
# called in this case.
|
200
|
+
def track_details
|
201
|
+
unless @read == false
|
202
|
+
track_number = self.first_track_num - 1
|
203
|
+
tracks = []
|
204
|
+
|
205
|
+
self.tracks do |offset, length|
|
206
|
+
track_number += 1
|
207
|
+
track_info = TrackInfo.new(track_number, offset, length)
|
208
|
+
|
209
|
+
if block_given?
|
210
|
+
yield track_info
|
211
|
+
else
|
212
|
+
tracks << track_info
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
return tracks unless block_given?
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Converts sectors to seconds.
|
221
|
+
#
|
222
|
+
# According to the red book standard 75 sectors are one second.
|
223
|
+
def self.sectors_to_seconds(sectors)
|
224
|
+
return (sectors.to_f / 75).round
|
84
225
|
end
|
85
226
|
|
86
227
|
end
|
data/test/test_discid.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: test_discid.rb
|
1
|
+
# $Id: test_discid.rb 236 2009-05-07 05:58:07Z phw $
|
2
2
|
#
|
3
3
|
# Author:: Philipp Wolfer (mailto:phw@rubyforge.org)
|
4
4
|
# Copyright:: Copyright (c) 2007, Philipp Wolfer
|
@@ -26,10 +26,11 @@ class TestDiscID < Test::Unit::TestCase
|
|
26
26
|
@fiction_first_track = 1
|
27
27
|
@fiction_last_track = 10
|
28
28
|
@fiction_sectors = 206535
|
29
|
+
@fiction_seconds = 2754
|
29
30
|
@fiction_offsets = [150, 18901, 39738, 59557, 79152, 100126,
|
30
31
|
124833, 147278, 166336, 182560]
|
31
32
|
@fiction_lengths = [18751, 20837, 19819, 19595, 20974,
|
32
|
-
24707, 22445, 19058, 16224, 23975]
|
33
|
+
24707, 22445, 19058, 16224, 23975]
|
33
34
|
end
|
34
35
|
|
35
36
|
def teardown
|
@@ -72,6 +73,7 @@ class TestDiscID < Test::Unit::TestCase
|
|
72
73
|
assert_equal nil, disc.first_track_num
|
73
74
|
assert_equal nil, disc.last_track_num
|
74
75
|
assert_equal nil, disc.sectors
|
76
|
+
assert_equal nil, disc.seconds
|
75
77
|
assert_equal nil, disc.tracks
|
76
78
|
|
77
79
|
# First erroneous put
|
@@ -81,6 +83,7 @@ class TestDiscID < Test::Unit::TestCase
|
|
81
83
|
assert_equal nil, disc.first_track_num
|
82
84
|
assert_equal nil, disc.last_track_num
|
83
85
|
assert_equal nil, disc.sectors
|
86
|
+
assert_equal nil, disc.seconds
|
84
87
|
assert_equal nil, disc.tracks
|
85
88
|
|
86
89
|
# Second successfull put
|
@@ -91,6 +94,7 @@ class TestDiscID < Test::Unit::TestCase
|
|
91
94
|
assert_equal @fiction_first_track, disc.first_track_num
|
92
95
|
assert_equal @fiction_last_track, disc.last_track_num
|
93
96
|
assert_equal @fiction_sectors, disc.sectors
|
97
|
+
assert_equal @fiction_seconds, disc.seconds
|
94
98
|
assert_equal @fiction_offsets, disc.tracks.map{|t| t[0]}
|
95
99
|
assert_equal @fiction_lengths, disc.tracks.map{|t| t[1]}
|
96
100
|
|
@@ -102,7 +106,68 @@ class TestDiscID < Test::Unit::TestCase
|
|
102
106
|
assert_equal nil, disc.first_track_num
|
103
107
|
assert_equal nil, disc.last_track_num
|
104
108
|
assert_equal nil, disc.sectors
|
109
|
+
assert_equal nil, disc.seconds
|
105
110
|
assert_equal nil, disc.tracks
|
106
111
|
end
|
107
112
|
|
113
|
+
# Test the track info method and TrackInfo objects
|
114
|
+
def test_track_details
|
115
|
+
disc = MusicBrainz::DiscID.new
|
116
|
+
|
117
|
+
assert_equal nil, disc.track_details
|
118
|
+
assert_nothing_raised {disc.put(@fiction_first_track, @fiction_sectors,
|
119
|
+
@fiction_offsets)}
|
120
|
+
|
121
|
+
|
122
|
+
# Save a block for testing each track
|
123
|
+
number = 0
|
124
|
+
proc_test_track = lambda do |track|
|
125
|
+
assert_equal number + 1, track.number
|
126
|
+
|
127
|
+
assert_equal @fiction_offsets[number], track.start_sector
|
128
|
+
assert_equal @fiction_lengths[number], track.sectors
|
129
|
+
assert_equal @fiction_offsets[number]+ @fiction_lengths[number],
|
130
|
+
track.end_sector
|
131
|
+
|
132
|
+
assert_equal MusicBrainz::DiscID.sectors_to_seconds(@fiction_offsets[number]),
|
133
|
+
track.start_time
|
134
|
+
assert_equal MusicBrainz::DiscID.sectors_to_seconds(@fiction_lengths[number]),
|
135
|
+
track.seconds
|
136
|
+
assert_equal MusicBrainz::DiscID.sectors_to_seconds(
|
137
|
+
@fiction_offsets[number]+ @fiction_lengths[number]),
|
138
|
+
track.end_time
|
139
|
+
|
140
|
+
assert_equal track.number, track[:number]
|
141
|
+
assert_equal track.sectors, track[:sectors]
|
142
|
+
assert_equal track.start_sector, track[:start_sector]
|
143
|
+
assert_equal track.end_sector, track[:end_sector]
|
144
|
+
assert_equal track.seconds, track[:seconds]
|
145
|
+
assert_equal track.start_time, track[:start_time]
|
146
|
+
assert_equal track.end_time, track[:end_time]
|
147
|
+
|
148
|
+
assert_equal nil, track[:invalid_value]
|
149
|
+
|
150
|
+
number += 1
|
151
|
+
end
|
152
|
+
|
153
|
+
# Call track_info and retrieve an Array
|
154
|
+
track_info = []
|
155
|
+
assert_nothing_raised {track_info = disc.track_details}
|
156
|
+
assert track_info.is_a?(Array)
|
157
|
+
track_info.each(&proc_test_track)
|
158
|
+
assert_equal disc.last_track_num, number
|
159
|
+
|
160
|
+
# Calling track_info directly with a given block
|
161
|
+
number = 0 # Reset the number of tracks (the above block is a closure, so this works)
|
162
|
+
assert_equal nil, disc.track_details(&proc_test_track)
|
163
|
+
assert_equal disc.last_track_num, number
|
164
|
+
end
|
165
|
+
|
166
|
+
# Test the conversion from sectors to seconds
|
167
|
+
def test_sectors_to_seconds
|
168
|
+
assert_equal 0, MusicBrainz::DiscID.sectors_to_seconds(0)
|
169
|
+
assert_equal @fiction_seconds,
|
170
|
+
MusicBrainz::DiscID.sectors_to_seconds(@fiction_sectors)
|
171
|
+
end
|
172
|
+
|
108
173
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: mb-discid
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date:
|
6
|
+
version: 0.1.3
|
7
|
+
date: 2009-11-19 00:00:00 +01:00
|
8
8
|
summary: Ruby bindings for libdiscid.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -19,9 +19,9 @@ bindir: bin
|
|
19
19
|
has_rdoc: true
|
20
20
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
21
|
requirements:
|
22
|
-
- - "
|
22
|
+
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
24
|
+
version: 1.8.6
|
25
25
|
version:
|
26
26
|
platform: ruby
|
27
27
|
signing_key:
|