wahwah 1.0.0 → 1.3.0
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.
- checksums.yaml +4 -4
- data/lib/wahwah/asf/object.rb +7 -12
- data/lib/wahwah/asf_tag.rb +199 -198
- data/lib/wahwah/errors.rb +2 -1
- data/lib/wahwah/flac/block.rb +8 -14
- data/lib/wahwah/flac/streaminfo_block.rb +5 -5
- data/lib/wahwah/flac_tag.rb +65 -63
- data/lib/wahwah/helper.rb +8 -8
- data/lib/wahwah/id3/comment_frame_body.rb +1 -1
- data/lib/wahwah/id3/frame.rb +57 -61
- data/lib/wahwah/id3/frame_body.rb +6 -7
- data/lib/wahwah/id3/image_frame_body.rb +5 -5
- data/lib/wahwah/id3/text_frame_body.rb +1 -1
- data/lib/wahwah/id3/v1.rb +59 -58
- data/lib/wahwah/id3/v2.rb +42 -35
- data/lib/wahwah/id3/v2_header.rb +4 -4
- data/lib/wahwah/lazy_read.rb +40 -0
- data/lib/wahwah/mp3/mpeg_frame_header.rb +39 -37
- data/lib/wahwah/mp3/vbri_header.rb +2 -2
- data/lib/wahwah/mp3/xing_header.rb +4 -4
- data/lib/wahwah/mp3_tag.rb +52 -51
- data/lib/wahwah/mp4/atom.rb +30 -34
- data/lib/wahwah/mp4_tag.rb +102 -91
- data/lib/wahwah/ogg/flac_tag.rb +3 -3
- data/lib/wahwah/ogg/opus_tag.rb +3 -3
- data/lib/wahwah/ogg/packets.rb +2 -2
- data/lib/wahwah/ogg/page.rb +3 -3
- data/lib/wahwah/ogg/vorbis_comment.rb +15 -15
- data/lib/wahwah/ogg/vorbis_tag.rb +2 -2
- data/lib/wahwah/ogg_tag.rb +34 -34
- data/lib/wahwah/riff/chunk.rb +11 -15
- data/lib/wahwah/riff_tag.rb +81 -79
- data/lib/wahwah/tag.rb +22 -10
- data/lib/wahwah/version.rb +1 -1
- data/lib/wahwah.rb +58 -53
- metadata +28 -14
data/lib/wahwah/flac_tag.rb
CHANGED
@@ -5,80 +5,82 @@ module WahWah
|
|
5
5
|
include Ogg::VorbisComment
|
6
6
|
include Flac::StreaminfoBlock
|
7
7
|
|
8
|
-
TAG_ID =
|
8
|
+
TAG_ID = "fLaC"
|
9
9
|
|
10
10
|
private
|
11
|
-
# FLAC structure:
|
12
|
-
#
|
13
|
-
# The four byte string "fLaC"
|
14
|
-
# The STREAMINFO metadata block
|
15
|
-
# Zero or more other metadata blocks
|
16
|
-
# One or more audio frames
|
17
|
-
def parse
|
18
|
-
# Flac file maybe contain ID3 header on the start, so skip it if exists
|
19
|
-
id3_header = ID3::V2Header.new(@file_io)
|
20
|
-
id3_header.valid? ? @file_io.seek(id3_header.size) : @file_io.rewind
|
21
11
|
|
22
|
-
|
12
|
+
# FLAC structure:
|
13
|
+
#
|
14
|
+
# The four byte string "fLaC"
|
15
|
+
# The STREAMINFO metadata block
|
16
|
+
# Zero or more other metadata blocks
|
17
|
+
# One or more audio frames
|
18
|
+
def parse
|
19
|
+
# Flac file maybe contain ID3 header on the start, so skip it if exists
|
20
|
+
id3_header = ID3::V2Header.new(@file_io)
|
21
|
+
id3_header.valid? ? @file_io.seek(id3_header.size) : @file_io.rewind
|
23
22
|
|
24
|
-
|
25
|
-
block = Flac::Block.new(@file_io)
|
26
|
-
parse_block(block)
|
23
|
+
return if @file_io.read(4) != TAG_ID
|
27
24
|
|
28
|
-
|
29
|
-
|
25
|
+
loop do
|
26
|
+
block = Flac::Block.new(@file_io)
|
27
|
+
parse_block(block)
|
28
|
+
|
29
|
+
break if block.is_last? || @file_io.eof?
|
30
30
|
end
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
def parse_block(block)
|
34
|
+
return unless block.valid?
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
case block.type
|
37
|
+
when "STREAMINFO"
|
38
|
+
parse_streaminfo_block(block.data)
|
39
|
+
when "VORBIS_COMMENT"
|
40
|
+
parse_vorbis_comment(block.data)
|
41
|
+
when "PICTURE"
|
42
|
+
@images_data.push(block)
|
43
|
+
block.skip
|
44
|
+
else
|
45
|
+
block.skip
|
45
46
|
end
|
47
|
+
end
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
49
|
+
# PICTURE block data structure:
|
50
|
+
#
|
51
|
+
# Length(bit) Meaning
|
52
|
+
#
|
53
|
+
# 32 The picture type according to the ID3v2 APIC frame:
|
54
|
+
#
|
55
|
+
# 32 The length of the MIME type string in bytes.
|
56
|
+
#
|
57
|
+
# n*8 The MIME type string.
|
58
|
+
#
|
59
|
+
# 32 The length of the description string in bytes.
|
60
|
+
#
|
61
|
+
# n*8 The description of the picture, in UTF-8.
|
62
|
+
#
|
63
|
+
# 32 The width of the picture in pixels.
|
64
|
+
#
|
65
|
+
# 32 The height of the picture in pixels.
|
66
|
+
#
|
67
|
+
# 32 The color depth of the picture in bits-per-pixel.
|
68
|
+
#
|
69
|
+
# 32 For indexed-color pictures (e.g. GIF), the number of colors used, or 0 for non-indexed pictures.
|
70
|
+
#
|
71
|
+
# 32 The length of the picture data in bytes.
|
72
|
+
#
|
73
|
+
# n*8 The binary picture data.
|
74
|
+
def parse_image_data(picture_block)
|
75
|
+
block_content = StringIO.new(picture_block.data)
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
type_index, mime_type_length = block_content.read(8).unpack("NN")
|
78
|
+
mime_type = Helper.encode_to_utf8(block_content.read(mime_type_length))
|
79
|
+
description_length = block_content.read(4).unpack1("N")
|
80
|
+
data_length = block_content.read(description_length + 20).unpack1("#{"x" * (description_length + 16)}N")
|
81
|
+
data = block_content.read(data_length)
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
+
{data: data, mime_type: mime_type, type: ID3::ImageFrameBody::TYPES[type_index]}
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
data/lib/wahwah/helper.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module WahWah
|
4
4
|
module Helper
|
5
|
-
def self.encode_to_utf8(string, source_encoding:
|
5
|
+
def self.encode_to_utf8(string, source_encoding: "")
|
6
6
|
encoded_string = source_encoding.empty? ?
|
7
|
-
string.force_encoding(
|
8
|
-
string.encode(
|
7
|
+
string.force_encoding("utf-8") :
|
8
|
+
string.encode("utf-8", source_encoding, invalid: :replace, undef: :replace, replace: "")
|
9
9
|
|
10
|
-
encoded_string.valid_encoding? ? encoded_string.strip :
|
10
|
+
encoded_string.valid_encoding? ? encoded_string.strip : ""
|
11
11
|
end
|
12
12
|
|
13
13
|
# ID3 size is encoded with four bytes where may the most significant
|
@@ -15,7 +15,7 @@ module WahWah
|
|
15
15
|
# making a total of 28 bits. The zeroed bits are ignored
|
16
16
|
def self.id3_size_caculate(bits_string, has_zero_bit: true)
|
17
17
|
if has_zero_bit
|
18
|
-
bits_string.scan(/.{8}/).map { |byte_string| byte_string[1
|
18
|
+
bits_string.scan(/.{8}/).map { |byte_string| byte_string[1..] }.join.to_i(2)
|
19
19
|
else
|
20
20
|
bits_string.to_i(2)
|
21
21
|
end
|
@@ -26,12 +26,12 @@ module WahWah
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.file_format(file_path)
|
29
|
-
File.extname(file_path).downcase.delete(
|
29
|
+
File.extname(file_path).downcase.delete(".")
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.byte_string_to_guid(byte_string)
|
33
|
-
guid = byte_string.unpack(
|
34
|
-
[guid[0..7], guid[8..11], guid[12..15], guid[16..19], guid[20
|
33
|
+
guid = byte_string.unpack("NnnA*").pack("VvvA*").unpack1("H*")
|
34
|
+
[guid[0..7], guid[8..11], guid[12..15], guid[16..19], guid[20..]].join("-").upcase
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -10,7 +10,7 @@ module WahWah
|
|
10
10
|
# Short content description <textstring> $00 (00)
|
11
11
|
# The actual text <textstring>
|
12
12
|
def parse
|
13
|
-
encoding_id, _language, reset_content = @content.unpack(
|
13
|
+
encoding_id, _language, reset_content = @content.unpack("CA3a*")
|
14
14
|
encoding = ENCODING_MAPPING[encoding_id]
|
15
15
|
_description, comment_text = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
16
16
|
|
data/lib/wahwah/id3/frame.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'zlib'
|
4
|
-
|
5
3
|
module WahWah
|
6
4
|
module ID3
|
7
5
|
class Frame
|
6
|
+
prepend LazyRead
|
7
|
+
|
8
8
|
ID_MAPPING = {
|
9
9
|
# ID3v2.2 frame id
|
10
10
|
COM: :comment,
|
@@ -78,10 +78,9 @@ module WahWah
|
|
78
78
|
array[15] = :data_length_indicator
|
79
79
|
end
|
80
80
|
|
81
|
-
attr_reader :name
|
81
|
+
attr_reader :name
|
82
82
|
|
83
|
-
def initialize(
|
84
|
-
@file_io = file_io
|
83
|
+
def initialize(version)
|
85
84
|
@version = version
|
86
85
|
|
87
86
|
parse_frame_header
|
@@ -96,10 +95,8 @@ module WahWah
|
|
96
95
|
# So skip those 4 byte.
|
97
96
|
if compressed? || data_length_indicator?
|
98
97
|
@file_io.seek(4, IO::SEEK_CUR)
|
99
|
-
@size
|
98
|
+
@size -= 4
|
100
99
|
end
|
101
|
-
|
102
|
-
parse_body
|
103
100
|
end
|
104
101
|
|
105
102
|
def valid?
|
@@ -114,67 +111,66 @@ module WahWah
|
|
114
111
|
@flags.include? :data_length_indicator
|
115
112
|
end
|
116
113
|
|
114
|
+
def value
|
115
|
+
return unless @size > 0
|
117
116
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
# Size 3 * %xxxxxxxx
|
123
|
-
#
|
124
|
-
# ID3v2.3 frame header structure:
|
125
|
-
#
|
126
|
-
# Frame ID $xx xx xx xx (four characters)
|
127
|
-
# Size 4 * %xxxxxxxx
|
128
|
-
# Flags $xx xx
|
129
|
-
#
|
130
|
-
# ID3v2.4 frame header structure:
|
131
|
-
#
|
132
|
-
# Frame ID $xx xx xx xx (four characters)
|
133
|
-
# Size 4 * %0xxxxxxx
|
134
|
-
# Flags $xx xx
|
135
|
-
def parse_frame_header
|
136
|
-
header_size = @version == 2 ? 6 : 10
|
137
|
-
header_formate = @version == 2 ? 'A3B24' : 'A4B32B16'
|
138
|
-
id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)
|
139
|
-
|
140
|
-
@name = ID_MAPPING[id.to_sym]
|
141
|
-
@size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
|
142
|
-
@flags = parse_flags(flags_bits)
|
143
|
-
end
|
117
|
+
content = compressed? ? Zlib.inflate(data) : data
|
118
|
+
frame_body = frame_body_class.new(content, @version)
|
119
|
+
frame_body.value
|
120
|
+
end
|
144
121
|
|
145
|
-
|
146
|
-
return [] if flags_bits.nil?
|
122
|
+
private
|
147
123
|
|
148
|
-
|
149
|
-
|
150
|
-
|
124
|
+
# ID3v2.2 frame header structure:
|
125
|
+
#
|
126
|
+
# Frame ID $xx xx xx(tree characters)
|
127
|
+
# Size 3 * %xxxxxxxx
|
128
|
+
#
|
129
|
+
# ID3v2.3 frame header structure:
|
130
|
+
#
|
131
|
+
# Frame ID $xx xx xx xx (four characters)
|
132
|
+
# Size 4 * %xxxxxxxx
|
133
|
+
# Flags $xx xx
|
134
|
+
#
|
135
|
+
# ID3v2.4 frame header structure:
|
136
|
+
#
|
137
|
+
# Frame ID $xx xx xx xx (four characters)
|
138
|
+
# Size 4 * %0xxxxxxx
|
139
|
+
# Flags $xx xx
|
140
|
+
def parse_frame_header
|
141
|
+
header_size = @version == 2 ? 6 : 10
|
142
|
+
header_formate = @version == 2 ? "A3B24" : "A4B32B16"
|
143
|
+
id, size_bits, flags_bits = @file_io.read(header_size).unpack(header_formate)
|
144
|
+
|
145
|
+
@name = ID_MAPPING[id.to_sym]
|
146
|
+
@size = Helper.id3_size_caculate(size_bits, has_zero_bit: @version == 4)
|
147
|
+
@flags = parse_flags(flags_bits)
|
148
|
+
end
|
151
149
|
|
152
|
-
|
153
|
-
|
154
|
-
end.compact
|
155
|
-
end
|
150
|
+
def parse_flags(flags_bits)
|
151
|
+
return [] if flags_bits.nil?
|
156
152
|
|
157
|
-
|
158
|
-
|
159
|
-
|
153
|
+
frame_flags_indications = @version == 4 ?
|
154
|
+
V4_HEADER_FLAGS_INDICATIONS :
|
155
|
+
V3_HEADER_FLAGS_INDICATIONS
|
160
156
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
157
|
+
flags_bits.chars.map.with_index do |flag_bit, index|
|
158
|
+
frame_flags_indications[index] if flag_bit == "1"
|
159
|
+
end.compact
|
160
|
+
end
|
165
161
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
end
|
162
|
+
def frame_body_class
|
163
|
+
case @name
|
164
|
+
when :comment
|
165
|
+
CommentFrameBody
|
166
|
+
when :genre
|
167
|
+
GenreFrameBody
|
168
|
+
when :image
|
169
|
+
ImageFrameBody
|
170
|
+
else
|
171
|
+
TextFrameBody
|
177
172
|
end
|
173
|
+
end
|
178
174
|
end
|
179
175
|
end
|
180
176
|
end
|
@@ -9,16 +9,15 @@ module WahWah
|
|
9
9
|
# $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM.
|
10
10
|
# $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
|
11
11
|
# $03 UTF-8 [UTF-8] encoded Unicode [UNICODE].
|
12
|
-
ENCODING_MAPPING = %w
|
12
|
+
ENCODING_MAPPING = %w[ISO-8859-1 UTF-16 UTF-16BE UTF-8]
|
13
13
|
|
14
14
|
ENCODING_TERMINATOR_SIZE = {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
"ISO-8859-1" => 1,
|
16
|
+
"UTF-16" => 2,
|
17
|
+
"UTF-16BE" => 2,
|
18
|
+
"UTF-8" => 1
|
19
19
|
}
|
20
20
|
|
21
|
-
|
22
21
|
attr_reader :value
|
23
22
|
|
24
23
|
def initialize(content, version)
|
@@ -29,7 +28,7 @@ module WahWah
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def parse
|
32
|
-
raise WahWahNotImplementedError,
|
31
|
+
raise WahWahNotImplementedError, "The parse method is not implemented"
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module WahWah
|
4
4
|
module ID3
|
5
5
|
class ImageFrameBody < FrameBody
|
6
|
-
TYPES = %i
|
6
|
+
TYPES = %i[
|
7
7
|
other
|
8
8
|
file_icon
|
9
9
|
other_file_icon
|
@@ -25,10 +25,10 @@ module WahWah
|
|
25
25
|
illustration
|
26
26
|
band_logotype
|
27
27
|
publisher_logotype
|
28
|
-
|
28
|
+
]
|
29
29
|
|
30
30
|
def mime_type
|
31
|
-
mime_type = @mime_type.downcase.yield_self { |type| type ==
|
31
|
+
mime_type = @mime_type.downcase.yield_self { |type| type == "jpg" ? "jpeg" : type }
|
32
32
|
@version > 2 ? mime_type : "image/#{mime_type}"
|
33
33
|
end
|
34
34
|
|
@@ -48,12 +48,12 @@ module WahWah
|
|
48
48
|
# Description <text string according to encoding> $00 (00)
|
49
49
|
# Picture data <binary data>
|
50
50
|
def parse
|
51
|
-
frame_format = @version > 2 ?
|
51
|
+
frame_format = @version > 2 ? "CZ*Ca*" : "Ca3Ca*"
|
52
52
|
encoding_id, @mime_type, type_index, reset_content = @content.unpack(frame_format)
|
53
53
|
encoding = ENCODING_MAPPING[encoding_id]
|
54
54
|
_description, data = Helper.split_with_terminator(reset_content, ENCODING_TERMINATOR_SIZE[encoding])
|
55
55
|
|
56
|
-
@value = {
|
56
|
+
@value = {data: data, mime_type: mime_type, type: TYPES[type_index]}
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -8,7 +8,7 @@ module WahWah
|
|
8
8
|
# Text encoding $xx
|
9
9
|
# Information <text string according to encoding>
|
10
10
|
def parse
|
11
|
-
encoding_id, text = @content.unpack(
|
11
|
+
encoding_id, text = @content.unpack("Ca*")
|
12
12
|
@value = Helper.encode_to_utf8(text, source_encoding: ENCODING_MAPPING[encoding_id])
|
13
13
|
end
|
14
14
|
end
|
data/lib/wahwah/id3/v1.rb
CHANGED
@@ -4,44 +4,44 @@ module WahWah
|
|
4
4
|
module ID3
|
5
5
|
class V1 < Tag
|
6
6
|
TAG_SIZE = 128
|
7
|
-
TAG_ID =
|
8
|
-
DEFAULT_ENCODING =
|
7
|
+
TAG_ID = "TAG"
|
8
|
+
DEFAULT_ENCODING = "iso-8859-1"
|
9
9
|
GENRES = [
|
10
10
|
# Standard Genres
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
|
12
|
+
"Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop",
|
13
|
+
"R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative",
|
14
|
+
"Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
|
15
|
+
"Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid",
|
16
|
+
"House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
|
17
|
+
"Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic",
|
18
|
+
"Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream",
|
19
|
+
"Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk",
|
20
|
+
"Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes",
|
21
|
+
"Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro",
|
22
|
+
"Musical", "Rock & Roll", "Hard Rock",
|
23
23
|
|
24
24
|
# Winamp Extended Genres
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
"Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin",
|
26
|
+
"Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
|
27
|
+
"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
|
28
|
+
"Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass",
|
29
|
+
"Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
|
30
|
+
"Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock",
|
31
|
+
"Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House",
|
32
|
+
"Hardcore Techno", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat",
|
33
|
+
"Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Contemporary Christian", "Christian Rock",
|
34
34
|
|
35
35
|
# Added on WinAmp 1.91
|
36
|
-
|
36
|
+
"Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop",
|
37
37
|
|
38
38
|
# Added on WinAmp 5.6
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
"Abstract", "Art Rock", "Baroque", "Bhangra", "Big Beat", "Breakbeat", "Chillout",
|
40
|
+
"Downtempo", "Dub", "EBM", "Eclectic", "Electro", "Electroclash", "Emo",
|
41
|
+
"Experimental", "Garage", "Illbient", "Industro-Goth", "Jam Band", "Krautrock", "Leftfield",
|
42
|
+
"Lounge", "Math Rock", "New Romantic", "Nu-Breakz", "Post-Punk", "Post-Rock", "Psytrance",
|
43
|
+
"Shoegaze", "Space Rock", "Trop Rock", "World Music", "Neoclassical", "Audiobook", "Audio Theatre",
|
44
|
+
"Neue Deutsche Welle", "Podcast", "Indie Rock", "G-Funk", "Dubstep", "Garage Rock", "Psybient"
|
45
45
|
]
|
46
46
|
|
47
47
|
def size
|
@@ -49,7 +49,7 @@ module WahWah
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def version
|
52
|
-
|
52
|
+
"v1"
|
53
53
|
end
|
54
54
|
|
55
55
|
def valid?
|
@@ -57,40 +57,41 @@ module WahWah
|
|
57
57
|
end
|
58
58
|
|
59
59
|
private
|
60
|
-
# For ID3v1 info, see here https://en.wikipedia.org/wiki/ID3#ID3v1
|
61
|
-
#
|
62
|
-
# header 3 "TAG"
|
63
|
-
# title 30 30 characters of the title
|
64
|
-
# artist 30 30 characters of the artist name
|
65
|
-
# album 30 30 characters of the album name
|
66
|
-
# year 4 A four-digit year
|
67
|
-
# comment 28 or 30 The comment.
|
68
|
-
# zero-byte 1 If a track number is stored, this byte contains a binary 0.
|
69
|
-
# track 1 The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
|
70
|
-
# genre 1 Index in a list of genres, or 255
|
71
|
-
def parse
|
72
|
-
return unless @file_io.size >= TAG_SIZE
|
73
60
|
|
74
|
-
|
75
|
-
|
61
|
+
# For ID3v1 info, see here https://en.wikipedia.org/wiki/ID3#ID3v1
|
62
|
+
#
|
63
|
+
# header 3 "TAG"
|
64
|
+
# title 30 30 characters of the title
|
65
|
+
# artist 30 30 characters of the artist name
|
66
|
+
# album 30 30 characters of the album name
|
67
|
+
# year 4 A four-digit year
|
68
|
+
# comment 28 or 30 The comment.
|
69
|
+
# zero-byte 1 If a track number is stored, this byte contains a binary 0.
|
70
|
+
# track 1 The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
|
71
|
+
# genre 1 Index in a list of genres, or 255
|
72
|
+
def parse
|
73
|
+
return unless @file_io.size >= TAG_SIZE
|
76
74
|
|
77
|
-
|
75
|
+
@file_io.seek(-TAG_SIZE, IO::SEEK_END)
|
76
|
+
@id = Helper.encode_to_utf8(@file_io.read(3), source_encoding: DEFAULT_ENCODING)
|
78
77
|
|
79
|
-
|
80
|
-
@artist = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
81
|
-
@album = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
82
|
-
@year = Helper.encode_to_utf8(@file_io.read(4), source_encoding: DEFAULT_ENCODING)
|
78
|
+
return unless valid?
|
83
79
|
|
84
|
-
|
80
|
+
@title = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
81
|
+
@artist = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
82
|
+
@album = Helper.encode_to_utf8(@file_io.read(30), source_encoding: DEFAULT_ENCODING)
|
83
|
+
@year = Helper.encode_to_utf8(@file_io.read(4), source_encoding: DEFAULT_ENCODING)
|
85
84
|
|
86
|
-
|
87
|
-
@track = comment.getbyte(-1)
|
88
|
-
comment = comment.byteslice(0..-3)
|
89
|
-
end
|
85
|
+
comment = @file_io.read(30)
|
90
86
|
|
91
|
-
|
92
|
-
@
|
87
|
+
if comment.getbyte(-2) == 0
|
88
|
+
@track = comment.getbyte(-1)
|
89
|
+
comment = comment.byteslice(0..-3)
|
93
90
|
end
|
91
|
+
|
92
|
+
@comments.push(Helper.encode_to_utf8(comment, source_encoding: DEFAULT_ENCODING))
|
93
|
+
@genre = GENRES[@file_io.getbyte] || ""
|
94
|
+
end
|
94
95
|
end
|
95
96
|
end
|
96
97
|
end
|