mp3file 0.0.2
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.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +29 -0
- data/Rakefile +25 -0
- data/doc/id3v2.2.0.txt +1658 -0
- data/doc/id3v2.3.0.txt +2024 -0
- data/doc/id3v2.4.0-frames.txt +1732 -0
- data/doc/id3v2.4.0-structure.txt +731 -0
- data/lib/mp3file/id3v1_tag.rb +58 -0
- data/lib/mp3file/id3v2/bit_padded_int.rb +24 -0
- data/lib/mp3file/id3v2/frame_header.rb +84 -0
- data/lib/mp3file/id3v2/header.rb +67 -0
- data/lib/mp3file/id3v2/tag.rb +25 -0
- data/lib/mp3file/id3v2/text_frame.rb +4 -0
- data/lib/mp3file/id3v2/version.rb +40 -0
- data/lib/mp3file/id3v2.rb +12 -0
- data/lib/mp3file/mp3_file.rb +182 -0
- data/lib/mp3file/mp3_header.rb +109 -0
- data/lib/mp3file/version.rb +3 -0
- data/lib/mp3file/xing_header.rb +39 -0
- data/lib/mp3file.rb +12 -0
- data/mp3file.gemspec +26 -0
- data/spec/common_helpers.rb +12 -0
- data/spec/files/bret_96.mp3 +0 -0
- data/spec/files/bret_id3v1.mp3 +0 -0
- data/spec/files/bret_id3v2.mp3 +0 -0
- data/spec/files/bret_vbr_6.mp3 +0 -0
- data/spec/mp3file/id3v1_tag_spec.rb +62 -0
- data/spec/mp3file/id3v2/bit_padded_int_spec.rb +59 -0
- data/spec/mp3file/id3v2/frame_header_spec.rb +79 -0
- data/spec/mp3file/id3v2/header_spec.rb +137 -0
- data/spec/mp3file/id3v2/tag_spec.rb +22 -0
- data/spec/mp3file/id3v2/version_spec.rb +56 -0
- data/spec/mp3file/mp3_file_spec.rb +90 -0
- data/spec/mp3file/mp3_header_spec.rb +336 -0
- data/spec/mp3file/xing_header_spec.rb +75 -0
- metadata +117 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::ID3v1Tag do
|
7
|
+
it "rejects an ID3v1 tag if it doesn't begin with TAG" do
|
8
|
+
lambda { Mp3file::ID3v1Tag.new(StringIO.new("\x00" * 128)) }.
|
9
|
+
should(raise_error(Mp3file::InvalidID3v1TagError))
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "When created with a properly-formatted ID3v1 tag" do
|
13
|
+
subject do
|
14
|
+
title = "Big Dipper"; title += "\x00" * (30 - title.size)
|
15
|
+
artist = "Cracker"; artist += "\x00" * (30 - artist.size)
|
16
|
+
album = "The Golden Age"; album += "\x00" * (30 - album.size)
|
17
|
+
year = "1996"
|
18
|
+
comment = "This is a comment"; comment += "\x00" * (30 - comment.size)
|
19
|
+
genre = 17.chr
|
20
|
+
Mp3file::ID3v1Tag.new(StringIO.new('TAG' + title + artist + album + year + comment + genre))
|
21
|
+
end
|
22
|
+
|
23
|
+
its(:title) { should == 'Big Dipper' }
|
24
|
+
its(:artist) { should == 'Cracker' }
|
25
|
+
its(:album) { should == 'The Golden Age' }
|
26
|
+
its(:year) { should == '1996' }
|
27
|
+
its(:comment) { should == 'This is a comment' }
|
28
|
+
its(:track) { should == nil }
|
29
|
+
its(:genre) { should == 'Rock' }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "When created with a properly-formatted ID3v1.1 tag" do
|
33
|
+
subject do
|
34
|
+
title = "Big Dipper"; title += "\x00" * (30 - title.size)
|
35
|
+
artist = "Cracker"; artist += "\x00" * (30 - artist.size)
|
36
|
+
album = "The Golden Age"; album += "\x00" * (30 - album.size)
|
37
|
+
year = "1996"
|
38
|
+
comment = "This is a comment"; comment += "\x00" * (29 - comment.size)
|
39
|
+
tracknum = 3.chr
|
40
|
+
genre = 17.chr
|
41
|
+
Mp3file::ID3v1Tag.new(StringIO.new('TAG' + title + artist + album + year + comment + tracknum + genre))
|
42
|
+
end
|
43
|
+
|
44
|
+
its(:title) { should == 'Big Dipper' }
|
45
|
+
its(:artist) { should == 'Cracker' }
|
46
|
+
its(:album) { should == 'The Golden Age' }
|
47
|
+
its(:year) { should == '1996' }
|
48
|
+
its(:comment) { should == 'This is a comment' }
|
49
|
+
its(:track) { should == 3 }
|
50
|
+
its(:genre) { should == 'Rock' }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "When created with a blank ID3v1 tag" do
|
54
|
+
subject { Mp3file::ID3v1Tag.new(StringIO.new("TAG" + ("\x00" * 125))) }
|
55
|
+
its(:title) { should == nil }
|
56
|
+
its(:artist) { should == nil }
|
57
|
+
its(:album) { should == nil }
|
58
|
+
its(:comment) { should == nil }
|
59
|
+
its(:track) { should == nil }
|
60
|
+
its(:genre) { should == 'Blues' }
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../lib/mp3file'
|
2
|
+
|
3
|
+
describe Mp3file::ID3v2::BitPaddedInt do
|
4
|
+
describe ".unpad_number" do
|
5
|
+
it "returns 0 when unpadding 0" do
|
6
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0).should == 0
|
7
|
+
end
|
8
|
+
|
9
|
+
context "without specifying bits" do
|
10
|
+
it "returns the least significant 7 bits of each byte in a 4-byte number" do
|
11
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0xFF_FF_FF_FF).
|
12
|
+
should == 0x0F_FF_FF_FF
|
13
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0b0101_0101_0101_0101_0101_0101_0101_0101).
|
14
|
+
should == 0b0000_1010_1011_0101_0110_1010_1101_0101
|
15
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0b1010_1010_1010_1010_1010_1010_1010_1010).
|
16
|
+
should == 0b0000_0101_0100_1010_1001_0101_0010_1010
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "specifying bits as n" do
|
21
|
+
it "returns the least significant n bits from each byte of a 4-byte number" do
|
22
|
+
1.upto(7) do |n|
|
23
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0xFF_FF_FF_FF, n).
|
24
|
+
should == 16**n - 1
|
25
|
+
end
|
26
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0b0101_0101_0101_0101_0101_0101_0101_0101, 5).
|
27
|
+
should == 0b1010_1101_0110_1011_0101
|
28
|
+
Mp3file::ID3v2::BitPaddedInt.unpad_number(0b1010_1010_1010_1010_1010_1010_1010_1010, 3).
|
29
|
+
should == 0b1001_001_0010
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".pad_number" do
|
35
|
+
it "returns 0 when padding 0" do
|
36
|
+
Mp3file::ID3v2::BitPaddedInt.pad_number(0).should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
context "without specifying bits" do
|
40
|
+
it "keeps the least significant 28 bits of a 4-byte number and pads each byte with a 0" do
|
41
|
+
Mp3file::ID3v2::BitPaddedInt.pad_number(0xFF_FF_FF_FF).
|
42
|
+
should == 0x7F_7F_7F_7F
|
43
|
+
Mp3file::ID3v2::BitPaddedInt.pad_number(0b0101_0101_0101_0101_0101_0101_0101_0101).
|
44
|
+
should == 0b0010_1010_0101_0101_0010_1010_0101_0101
|
45
|
+
Mp3file::ID3v2::BitPaddedInt.pad_number(0b1010_1010_1010_1010_1010_1010_1010_1010).
|
46
|
+
should == 0b0101_0101_0010_1010_0101_0101_0010_1010
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "specifying bits as n" do
|
51
|
+
it "keeps the bottom n*4 bits and pads each byte with 0s" do
|
52
|
+
1.upto(7) do |n|
|
53
|
+
Mp3file::ID3v2::BitPaddedInt.pad_number(0xFF_FF_FF_FF, n).
|
54
|
+
should == (2**n - 1)*(256**3 + 256**2 + 256**1 + 1)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::ID3v2::FrameHeader do
|
7
|
+
context "with ID3v2.2 tags" do
|
8
|
+
let(:tag) { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x02\x00\x00\x00\x00\x00\x00")) }
|
9
|
+
|
10
|
+
describe("A 15-byte long TT2 frame header.") do
|
11
|
+
subject { Mp3file::ID3v2::FrameHeader.new(StringIO.new("TT2\x00\x00\x0f"), tag) }
|
12
|
+
its(:frame_id) { should == 'TT2' }
|
13
|
+
its(:size) { should == 15 }
|
14
|
+
its(:preserve_on_altered_tag) { should == false }
|
15
|
+
its(:preserve_on_altered_file) { should == false }
|
16
|
+
its(:read_only) { should == false }
|
17
|
+
its(:compressed) { should == false }
|
18
|
+
its(:encrypted) { should == false }
|
19
|
+
its(:encryption_type) { should be_nil }
|
20
|
+
its(:group) { should be_nil }
|
21
|
+
its(:unsynchronized) { should == false }
|
22
|
+
its(:data_length) { should == 0 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with ID3v2.3 tags" do
|
27
|
+
let(:tag) { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00")) }
|
28
|
+
|
29
|
+
describe("A header with invalid flag bits set") do
|
30
|
+
it("Should raise an error") do
|
31
|
+
io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
|
32
|
+
lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
|
33
|
+
should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe("A 9-byte TIT2 frame header.") do
|
38
|
+
subject { Mp3file::ID3v2::FrameHeader.new(StringIO.new("TIT2\x00\x00\x00\x09\x00\x00"), tag) }
|
39
|
+
its(:frame_id) { should == 'TIT2' }
|
40
|
+
its(:size) { should == 9 }
|
41
|
+
its(:preserve_on_altered_tag) { should == false }
|
42
|
+
its(:preserve_on_altered_file) { should == false }
|
43
|
+
its(:read_only) { should == false }
|
44
|
+
its(:compressed) { should == false }
|
45
|
+
its(:encrypted) { should == false }
|
46
|
+
its(:encryption_type) { should be_nil }
|
47
|
+
its(:group) { should be_nil }
|
48
|
+
its(:unsynchronized) { should == false }
|
49
|
+
its(:data_length) { should == 0 }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe("A TIT2 header with all of its flags set") do
|
53
|
+
subject { Mp3file::ID3v2::FrameHeader.new(StringIO.new("TIT2\x00\x00\x00\x09\x00\x00"), tag) }
|
54
|
+
its(:frame_id) { should == 'TIT2' }
|
55
|
+
its(:size) { should == 9 }
|
56
|
+
its(:preserve_on_altered_tag) { should == false }
|
57
|
+
its(:preserve_on_altered_file) { should == false }
|
58
|
+
its(:read_only) { should == false }
|
59
|
+
its(:compressed) { should == false }
|
60
|
+
its(:encrypted) { should == false }
|
61
|
+
its(:encryption_type) { should be_nil }
|
62
|
+
its(:group) { should be_nil }
|
63
|
+
its(:unsynchronized) { should == false }
|
64
|
+
its(:data_length) { should == 0 }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with ID3v2.4 tags" do
|
69
|
+
let(:tag) { Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x04\x00\x00\x00\x00\x00\x00")) }
|
70
|
+
|
71
|
+
describe("A header with invalid flag bits set") do
|
72
|
+
it("Should raise an error") do
|
73
|
+
io = StringIO.new("TIT2\x00\x00\x00\x09\x01\x00")
|
74
|
+
lambda { Mp3file::ID3v2::FrameHeader.new(io, tag) }.
|
75
|
+
should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::ID3v2::Header do
|
7
|
+
it "raises an error if the first 3 bytes don't say \"ID3\"" do
|
8
|
+
io = StringIO.new("ID2\x03\x00\x00\x00\x00\x00\x00")
|
9
|
+
lambda { Mp3file::ID3v2::Header.new(io) }.should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises an error if the major version is more than 4 (e.g., no ID3v2.5.0+)" do
|
13
|
+
io = StringIO.new("ID3\x05\x00\x00\x00\x00\x00\x00")
|
14
|
+
lambda { Mp3file::ID3v2::Header.new(io) }.should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises an error if the major version is less than 2 (e.g., no ID3v2.1.0)" do
|
18
|
+
io = StringIO.new("ID3\x01\x00\x00\x00\x00\x00\x00")
|
19
|
+
lambda { Mp3file::ID3v2::Header.new(io) }.should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "flags:" do
|
23
|
+
describe "An ID3v2.2 header with no set flags:" do
|
24
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x00\x00\x00\x00\x00")) }
|
25
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_2_0 }
|
26
|
+
its(:unsynchronized) { should == false }
|
27
|
+
its(:extended_header) { should == false }
|
28
|
+
its(:compression) { should == false }
|
29
|
+
its(:experimental) { should == false }
|
30
|
+
its(:footer) { should == false }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "An ID3v2.2 header with the unsync flag set:" do
|
34
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x80\x00\x00\x00\x00")) }
|
35
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_2_0 }
|
36
|
+
its(:unsynchronized) { should == true }
|
37
|
+
its(:extended_header) { should == false }
|
38
|
+
its(:compression) { should == false }
|
39
|
+
its(:experimental) { should == false }
|
40
|
+
its(:footer) { should == false }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "An ID3v2.2 header with the compression flag set:" do
|
44
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x40\x00\x00\x00\x00")) }
|
45
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_2_0 }
|
46
|
+
its(:unsynchronized) { should == false }
|
47
|
+
its(:extended_header) { should == false }
|
48
|
+
its(:compression) { should == true }
|
49
|
+
its(:experimental) { should == false }
|
50
|
+
its(:footer) { should == false }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "An ID3v2.2 header with an invalid flag set" do
|
54
|
+
it "raises an error" do
|
55
|
+
lambda { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x20\x00\x00\x00\x00")) }.
|
56
|
+
should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "An ID3v2.3 header with the extended header flag set:" do
|
61
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x40\x00\x00\x00\x00")) }
|
62
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_3_0 }
|
63
|
+
its(:unsynchronized) { should == false }
|
64
|
+
its(:extended_header) { should == true }
|
65
|
+
its(:compression) { should == false }
|
66
|
+
its(:experimental) { should == false }
|
67
|
+
its(:footer) { should == false }
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "An ID3v2.3 header with the experimental header flag set:" do
|
71
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x20\x00\x00\x00\x00")) }
|
72
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_3_0 }
|
73
|
+
its(:unsynchronized) { should == false }
|
74
|
+
its(:extended_header) { should == false }
|
75
|
+
its(:compression) { should == false }
|
76
|
+
its(:experimental) { should == true }
|
77
|
+
its(:footer) { should == false }
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "An ID3v2.3 header with the experimental header flag set:" do
|
81
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x20\x00\x00\x00\x00")) }
|
82
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_3_0 }
|
83
|
+
its(:unsynchronized) { should == false }
|
84
|
+
its(:extended_header) { should == false }
|
85
|
+
its(:compression) { should == false }
|
86
|
+
its(:experimental) { should == true }
|
87
|
+
its(:footer) { should == false }
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "An ID3v2.3 header with an invalid flag set" do
|
91
|
+
it "raises an error" do
|
92
|
+
lambda { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x10\x00\x00\x00\x00")) }.
|
93
|
+
should(raise_error(Mp3file::ID3v2::InvalidID3v2TagError))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "An ID3v2.4 header with the footer header flag set:" do
|
98
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x04\x00\x10\x00\x00\x00\x00")) }
|
99
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_4_0 }
|
100
|
+
its(:unsynchronized) { should == false }
|
101
|
+
its(:extended_header) { should == false }
|
102
|
+
its(:compression) { should == false }
|
103
|
+
its(:experimental) { should == false }
|
104
|
+
its(:footer) { should == true }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#version" do
|
109
|
+
it "detects ID3v2.2.0" do
|
110
|
+
t = Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x00\x00\x00\x00\x00"))
|
111
|
+
t.version.should == Mp3file::ID3v2::ID3V2_2_0
|
112
|
+
end
|
113
|
+
|
114
|
+
it "detects ID3v2.3.0" do
|
115
|
+
t = Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00"))
|
116
|
+
t.version.should == Mp3file::ID3v2::ID3V2_3_0
|
117
|
+
end
|
118
|
+
|
119
|
+
it "detects ID3v2.4.0" do
|
120
|
+
t = Mp3file::ID3v2::Header.new(StringIO.new("ID3\x04\x00\x00\x00\x00\x00\x00"))
|
121
|
+
t.version.should == Mp3file::ID3v2::ID3V2_4_0
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#size" do
|
126
|
+
it "properly reads the size of an ID3v2 tag" do
|
127
|
+
t = Mp3file::ID3v2::Header.new(StringIO.new("ID3\x03\x00\x00\x00\x06\x49\x37"))
|
128
|
+
t.tag_size.should == 107703
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "flags for ID3v2.2" do
|
133
|
+
describe "An ID3v2.2 header with no set flags" do
|
134
|
+
subject { Mp3file::ID3v2::Header.new(StringIO.new("ID3\x02\x00\x00\x00\x00\x00\x00")) }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::ID3v2::Tag do
|
7
|
+
describe "An empty tag" do
|
8
|
+
subject do
|
9
|
+
t = Mp3file::ID3v2::Tag.new(StringIO.new("ID3\x03\x00\x00\x00\x00\x00\x00"))
|
10
|
+
t.load_frames
|
11
|
+
t
|
12
|
+
end
|
13
|
+
its(:version) { should == Mp3file::ID3v2::ID3V2_3_0 }
|
14
|
+
its(:unsynchronized) { should == false }
|
15
|
+
its(:extended_header) { should == false }
|
16
|
+
its(:compression) { should == false }
|
17
|
+
its(:experimental) { should == false }
|
18
|
+
its(:footer) { should == false }
|
19
|
+
its(:size) { should == 10 }
|
20
|
+
its(:frames) { should == [] }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::ID3v2::Version do
|
7
|
+
describe Mp3file::ID3v2::ID3V2_2_0 do
|
8
|
+
subject { Mp3file::ID3v2::ID3V2_2_0 }
|
9
|
+
its(:vbig) { should == 2 }
|
10
|
+
its(:vmaj) { should == 2 }
|
11
|
+
its(:vmin) { should == 0 }
|
12
|
+
its(:to_s) { should == 'ID3v2.2.0' }
|
13
|
+
its(:to_byte_string) { should == "\x02\x00" }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Mp3file::ID3v2::ID3V2_3_0 do
|
17
|
+
subject { Mp3file::ID3v2::ID3V2_3_0 }
|
18
|
+
its(:vbig) { should == 2 }
|
19
|
+
its(:vmaj) { should == 3 }
|
20
|
+
its(:vmin) { should == 0 }
|
21
|
+
its(:to_s) { should == 'ID3v2.3.0' }
|
22
|
+
its(:to_byte_string) { should == "\x03\x00" }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Mp3file::ID3v2::ID3V2_4_0 do
|
26
|
+
subject { Mp3file::ID3v2::ID3V2_4_0 }
|
27
|
+
its(:vbig) { should == 2 }
|
28
|
+
its(:vmaj) { should == 4 }
|
29
|
+
its(:vmin) { should == 0 }
|
30
|
+
its(:to_s) { should == 'ID3v2.4.0' }
|
31
|
+
its(:to_byte_string) { should == "\x04\x00" }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#<=>" do
|
35
|
+
it("should recognize that ID3v2.2 < ID3v2.3") do
|
36
|
+
(Mp3file::ID3v2::ID3V2_2_0 <=> Mp3file::ID3v2::ID3V2_3_0).should == -1
|
37
|
+
end
|
38
|
+
|
39
|
+
it("should recognize that ID3v2.4 > ID3v2.2") do
|
40
|
+
(Mp3file::ID3v2::ID3V2_4_0 <=> Mp3file::ID3v2::ID3V2_2_0).should == 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it("should recognize that ID3v2.3 == ID3v2.3") do
|
44
|
+
(Mp3file::ID3v2::ID3V2_3_0 <=> Mp3file::ID3v2::ID3V2_3_0).should == 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#new" do
|
49
|
+
subject { Mp3file::ID3v2::Version.new(3, 1) }
|
50
|
+
its(:vbig) { should == 2 }
|
51
|
+
its(:vmaj) { should == 3 }
|
52
|
+
its(:vmin) { should == 1 }
|
53
|
+
its(:to_s) { should == 'ID3v2.3.1' }
|
54
|
+
its(:to_byte_string) { should == "\x03\x01" }
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../lib/mp3file'
|
2
|
+
require File.dirname(__FILE__) + '/../common_helpers'
|
3
|
+
|
4
|
+
include CommonHelpers
|
5
|
+
|
6
|
+
describe Mp3file::MP3File do
|
7
|
+
describe "A 96 kbps 32 kHz Joint Stereo CBR file without any ID3 tags" do
|
8
|
+
subject { Mp3file::MP3File.new(fixture_file('bret_96.mp3')) }
|
9
|
+
its(:id3v2tag?) { should == false }
|
10
|
+
its(:id3v1tag?) { should == false }
|
11
|
+
its("file.path") { should == fixture_file('bret_96.mp3').to_s }
|
12
|
+
its("file.closed?") { should == true }
|
13
|
+
its(:file_size) { should == fixture_file('bret_96.mp3').size }
|
14
|
+
its(:audio_size) { should == fixture_file('bret_96.mp3').size }
|
15
|
+
its(:first_header_offset) { should == 0 }
|
16
|
+
its(:mpeg_version) { should == 'MPEG 1' }
|
17
|
+
its(:layer) { should == 'Layer III' }
|
18
|
+
its(:bitrate) { should == 96 }
|
19
|
+
its(:samplerate) { should == 32000 }
|
20
|
+
its(:mode) { should == 'Joint Stereo' }
|
21
|
+
its(:num_frames) { should == 141 }
|
22
|
+
its(:total_samples) { should == 162432 }
|
23
|
+
its(:length) { should == 5 }
|
24
|
+
its(:vbr?) { should == false }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "a 44.1 kHz Stereo VBR file with an average bitrate of 13 kbps without any ID3 tags" do
|
28
|
+
subject { Mp3file::MP3File.new(fixture_file('bret_vbr_6.mp3')) }
|
29
|
+
its(:id3v2tag?) { should == false }
|
30
|
+
its(:id3v1tag?) { should == false }
|
31
|
+
its("file.path") { should == fixture_file('bret_vbr_6.mp3').to_s }
|
32
|
+
its("file.closed?") { should == true }
|
33
|
+
its(:file_size) { should == fixture_file('bret_vbr_6.mp3').size }
|
34
|
+
its(:audio_size) { should == 81853 }
|
35
|
+
its(:first_header_offset) { should == 0 }
|
36
|
+
its(:mpeg_version) { should == 'MPEG 1' }
|
37
|
+
its(:layer) { should == 'Layer III' }
|
38
|
+
its(:bitrate) { should == 130 }
|
39
|
+
its(:samplerate) { should == 44100 }
|
40
|
+
its(:mode) { should == 'Stereo' }
|
41
|
+
its(:num_frames) { should == 193 }
|
42
|
+
its(:total_samples) { should == 222336 }
|
43
|
+
its(:length) { should == 5 }
|
44
|
+
its(:vbr?) { should == true }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "A 96 kbps 32 kHz CBR file with only an ID3v1 tag" do
|
48
|
+
subject { Mp3file::MP3File.new(fixture_file('bret_id3v1.mp3')) }
|
49
|
+
its(:id3v2tag?) { should == false }
|
50
|
+
its(:id3v1tag?) { should == true }
|
51
|
+
its(:audio_size) { should == 60912 }
|
52
|
+
its(:first_header_offset) { should == 0 }
|
53
|
+
its(:mpeg_version) { should == 'MPEG 1' }
|
54
|
+
its(:layer) { should == 'Layer III' }
|
55
|
+
its(:bitrate) { should == 96 }
|
56
|
+
its(:samplerate) { should == 32000 }
|
57
|
+
its(:mode) { should == 'Joint Stereo' }
|
58
|
+
its(:num_frames) { should == 141 }
|
59
|
+
its(:total_samples) { should == 162432 }
|
60
|
+
its(:length) { should == 5 }
|
61
|
+
its(:vbr?) { should == false }
|
62
|
+
its('id3v1_tag.artist') { should == 'Cracker' }
|
63
|
+
its(:title) { should == 'Hey Bret (You Know What Time I' }
|
64
|
+
its(:album) { should == 'Sunrise in the Land of Milk an' }
|
65
|
+
its(:comment) { should == 'For testing the mp3file gem' }
|
66
|
+
its(:year) { should == '2009' }
|
67
|
+
its(:track) { should == 9 }
|
68
|
+
its(:genre) { should == 'Rock' }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "A 96 kbps 34 kHz Joint Stereo CBR file with an ID3v2 tag" do
|
72
|
+
subject { Mp3file::MP3File.new(fixture_file('bret_id3v2.mp3')) }
|
73
|
+
# its(:id3v2tag?) { should == true }
|
74
|
+
its(:id3v1tag?) { should == false }
|
75
|
+
its("file.path") { should == fixture_file('bret_id3v2.mp3').to_s }
|
76
|
+
its("file.closed?") { should == true }
|
77
|
+
its(:file_size) { should == fixture_file('bret_id3v2.mp3').size }
|
78
|
+
its(:audio_size) { should == 60912 }
|
79
|
+
its(:first_header_offset) { should == 528 }
|
80
|
+
its(:mpeg_version) { should == 'MPEG 1' }
|
81
|
+
its(:layer) { should == 'Layer III' }
|
82
|
+
its(:bitrate) { should == 96 }
|
83
|
+
its(:samplerate) { should == 32000 }
|
84
|
+
its(:mode) { should == 'Joint Stereo' }
|
85
|
+
its(:num_frames) { should == 141 }
|
86
|
+
its(:total_samples) { should == 162432 }
|
87
|
+
its(:length) { should == 5 }
|
88
|
+
its(:vbr?) { should == false }
|
89
|
+
end
|
90
|
+
end
|