riff 0.1
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/Rakefile +9 -0
- data/examples/example1.rb +16 -0
- data/examples/example2.rb +6 -0
- data/lib/riff/base.rb +285 -0
- data/lib/riff/bwav.rb +8 -0
- data/lib/riff/wav.rb +8 -0
- data/test/riff_test.rb +130 -0
- data/test/riff_test_suite.rb +4 -0
- data/test/wav_test.rb +44 -0
- data/test_media/Pop.wav +0 -0
- data/test_media/bad.riff +1 -0
- metadata +51 -0
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'lib/riff/base.rb'
|
2
|
+
|
3
|
+
def print_chunk(ck,margin = "")
|
4
|
+
if ck.is_list? then
|
5
|
+
puts margin + "+ '%s' (%s): %i bytes" % [ck.fourcc , ck.signature , ck.length ]
|
6
|
+
ck.each_with_index do |k,i|
|
7
|
+
print_chunk(k,margin + " " + " ")
|
8
|
+
end
|
9
|
+
else
|
10
|
+
puts margin + "- '%s' : %i bytes" % [ck.fourcc , ck.length ]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Riff::Base.open(ARGV[0],"r") do |wav|
|
15
|
+
print_chunk( wav.root_chunk )
|
16
|
+
end
|
data/lib/riff/base.rb
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
#--
|
2
|
+
#riff.rb -- API for reading generic Microsoft RIFF Files
|
3
|
+
#Copyright (C) 2006 Jamie Hardt
|
4
|
+
|
5
|
+
#This library is free software; you can redistribute it and/or
|
6
|
+
#modify it under the terms of the GNU Lesser General Public
|
7
|
+
#License as published by the Free Software Foundation; either
|
8
|
+
#version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
#This library is distributed in the hope that it will be useful,
|
11
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
#Lesser General Public License for more details.
|
14
|
+
|
15
|
+
#You should have received a copy of the GNU Lesser General Public
|
16
|
+
#License along with this library; if not, write to the Free Software
|
17
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
# This library allows for the reading of RIFF (Resource Interchange File Format)
|
22
|
+
# files. Opening a RIFF file with the Riff.open method allows the individual
|
23
|
+
# chunks of the file to be accessed through the Riff#root_chunk method, and
|
24
|
+
# this object mixes-in Enumerable in order to allow iteration over each chunk
|
25
|
+
# and its sub-chunks (when applicable).
|
26
|
+
#
|
27
|
+
# Author:: Jamie Hardt
|
28
|
+
# License:: The Lesser GPL
|
29
|
+
#
|
30
|
+
# ---
|
31
|
+
#
|
32
|
+
# = Examples
|
33
|
+
# === Getting iXML metadata from a broadcast-WAV file
|
34
|
+
#
|
35
|
+
# require 'riff/base'
|
36
|
+
# Riff::Base.open(ARGV[0],"r") do |wav|
|
37
|
+
# xml = wav.root_chunk['ixml'].body
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# === Listing all the chunks in a file
|
41
|
+
# require 'riff/base'
|
42
|
+
#
|
43
|
+
# def print_chunk(ck,margin = "")
|
44
|
+
# if ck.is_list? then
|
45
|
+
# puts margin + "+ %s (%s): %i bytes" % \
|
46
|
+
# [ck.fourcc , ck.signature , ck.length ]
|
47
|
+
# ck.each_with_index do |k,i|
|
48
|
+
# print_chunk(k,margin + " ")
|
49
|
+
# end
|
50
|
+
# else
|
51
|
+
# puts margin + "- %s : %i bytes" % [ck.fourcc , ck.length ]
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# Riff::Base.open(ARGV[0],"r") do |wav|
|
56
|
+
# print_chunk( wav.root_chunk )
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
module Riff
|
60
|
+
|
61
|
+
module VERSION
|
62
|
+
MAJOR = 0
|
63
|
+
MINOR = 1
|
64
|
+
end #module version
|
65
|
+
|
66
|
+
class Base
|
67
|
+
# The Riff class provides a front-end to the other objects of the library.
|
68
|
+
# It's the only object that you interact with directly, and calling its methods
|
69
|
+
# will return the other objects of the class.
|
70
|
+
|
71
|
+
# Returns the File object for this Riff object.
|
72
|
+
attr_reader :file
|
73
|
+
|
74
|
+
# Opens a RIFF file for reading. Pass a string path and string mode, as you would
|
75
|
+
# for File::open. A Riff object will be returned.
|
76
|
+
# * At this time, only the "r" and "rb" modes are supported, others will raise
|
77
|
+
# and ArgumentError
|
78
|
+
# * If you provide a block, the Riff object will be yielded to the block as the
|
79
|
+
# sole parameter, and will be automatically closed at the end of the block.
|
80
|
+
# * If you pass a file which does not start with the RIFF fourcc, the file
|
81
|
+
# is invalid and a FileTypeError will be thrown.
|
82
|
+
def self.open(path,mode) # :yields: riff_object
|
83
|
+
riff_obj = Riff::Base.new(path,mode)
|
84
|
+
if block_given? && riff_obj then
|
85
|
+
yield riff_obj
|
86
|
+
riff_obj.close
|
87
|
+
end
|
88
|
+
riff_obj
|
89
|
+
end
|
90
|
+
|
91
|
+
# Class method for called by subclasses to set-up validations. If you
|
92
|
+
# write a subclass of the Riff object, say for reading AVIs, you can
|
93
|
+
# add validation code by calling this class method in your class like so:
|
94
|
+
#
|
95
|
+
# class RiffAVI
|
96
|
+
#
|
97
|
+
# validate do |riff|
|
98
|
+
# riff.root_chunk.signature == 'AVI '
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# ... class continues...
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# You provide a block, which is yielded the Riff object at the time
|
105
|
+
# it is created, and ths block should return either +true+ or +false+.
|
106
|
+
# If it returns +true+, the Riff subclass instance will be created. If
|
107
|
+
# the block returns +false+, the .new class method will return nil.
|
108
|
+
#
|
109
|
+
# Subclass validation methods are called in the order of the subclasses
|
110
|
+
# inheiritance, so that if you wrote a broadcast-wav class that inheirited
|
111
|
+
# from a wave class that inheirited from Riff, Riff's validate()
|
112
|
+
# would be called first, and then the wave validate(), and the bwav's validate().
|
113
|
+
# Thus, a subclass can run its validations with the guarantee that the Riff
|
114
|
+
# in question passed its validations for its superclass.
|
115
|
+
def self.validate(&block)
|
116
|
+
raise ArgumentError unless block.arity == 1
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the Root Chunk of the RIFF file as a ListChunk
|
121
|
+
def root_chunk
|
122
|
+
@file.rewind
|
123
|
+
the_chunk = Chunk.read_chunk(@file)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Closes the Riff object. Subsequent calls to the Riff object or any of its
|
127
|
+
# chunk objects will fail.
|
128
|
+
def close
|
129
|
+
@file.close
|
130
|
+
end
|
131
|
+
|
132
|
+
class FileTypeError < StandardError ; end #:nodoc:
|
133
|
+
|
134
|
+
protected
|
135
|
+
|
136
|
+
def valid?
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def initialize(path, mode)
|
143
|
+
raise(ArgumentError, "Riff.open only supports mode 'r' or 'rb'.") \
|
144
|
+
unless mode == "r" || mode == "rb"
|
145
|
+
|
146
|
+
@file = File.open(path,mode)
|
147
|
+
return nil unless valid?
|
148
|
+
end #def initialize
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
class Base
|
154
|
+
|
155
|
+
# The Chunk object represents a chunk of a larger RIFF file. The chunk may be
|
156
|
+
# interrogated to reveal its fourcc and the size of its body. The chunk also
|
157
|
+
# provides the +body+ method to access the stream of data within the chunk.
|
158
|
+
# Keep in mind that this bit of data can be very, very large in media files
|
159
|
+
# (like .wav files) and that reading them in a language like ruby will be quite
|
160
|
+
# slow.
|
161
|
+
|
162
|
+
class Chunk
|
163
|
+
|
164
|
+
# the four-character code of this chunk, always four characters long
|
165
|
+
# (shorter fourcc's are padded with spaces)
|
166
|
+
attr_reader :fourcc
|
167
|
+
|
168
|
+
# the length of the body of the chunk (the length of the chunk minus
|
169
|
+
# the the fourcc and length bytes; thus the length of the chunk - 8)
|
170
|
+
# This data is read directly from the chunk's preamble and calling
|
171
|
+
# this is much, much faster than body.size
|
172
|
+
attr_reader :length
|
173
|
+
|
174
|
+
# the offset of this chunk from the start of its file
|
175
|
+
attr_reader :offset
|
176
|
+
|
177
|
+
|
178
|
+
def self.read_chunk(fp) #:nodoc:
|
179
|
+
code = fp.read(4)
|
180
|
+
fp.pos -= 4
|
181
|
+
if code == "RIFF" or code == "LIST" then
|
182
|
+
ListChunk.new(fp)
|
183
|
+
else
|
184
|
+
Chunk.new(fp)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Reads the entire body of the chunk (all of the data following the fourcc and size)
|
189
|
+
def body
|
190
|
+
@file.pos = @offset + 8
|
191
|
+
@file.read @length
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns <tt>true</tt> if this object is a ListChunk. A convenience to typing
|
195
|
+
# <tt>instance_of? Riff::ListChunk</tt>
|
196
|
+
def is_list?
|
197
|
+
instance_of? Riff::Base::ListChunk
|
198
|
+
end
|
199
|
+
|
200
|
+
def each_byte
|
201
|
+
while @file.pos < @offset + 8 + @length
|
202
|
+
yield @file.getc
|
203
|
+
@file.pos +=1
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
protected
|
208
|
+
|
209
|
+
def Chunk.read_bytes_to_int(file,bytes) # :nodoc:
|
210
|
+
|
211
|
+
ary = [ ]
|
212
|
+
bytes.times { ary << file.getc }
|
213
|
+
|
214
|
+
result = 0
|
215
|
+
ary.each_with_index do |n, i|
|
216
|
+
7.downto(0) do |bit|
|
217
|
+
result += 2 ** ((bit) + i * 8) if n[bit] == 1
|
218
|
+
end
|
219
|
+
end
|
220
|
+
return result
|
221
|
+
end
|
222
|
+
|
223
|
+
def initialize(fp) #:nodoc:
|
224
|
+
@file = fp
|
225
|
+
@offset = @file.pos
|
226
|
+
@fourcc = @file.read(4)
|
227
|
+
@length = Chunk.read_bytes_to_int(@file,4)
|
228
|
+
end
|
229
|
+
|
230
|
+
end #class Chunk
|
231
|
+
|
232
|
+
# ListChunk is a subclass of Chunk, and so you can access its fourcc and size
|
233
|
+
#
|
234
|
+
# <em>Note:</em> The +body+ method is not permitted on ListChunk
|
235
|
+
class ListChunk < Chunk
|
236
|
+
|
237
|
+
include Enumerable
|
238
|
+
|
239
|
+
# The four-character signature of the container chunk.
|
240
|
+
# In the case of a RIFF WAV container, this is "WAVE"
|
241
|
+
attr_reader :signature
|
242
|
+
|
243
|
+
# Accesses the chunks of the file by either a fourcc, an index, or a range.
|
244
|
+
# Be aware that ListChunks may contain many children chunk with the same
|
245
|
+
# fourcc, so using the index will always get you a paticular one, while
|
246
|
+
# using the fourcc will only get you the first of a class.
|
247
|
+
def [](chunk_spec) # :return: array or Chunk
|
248
|
+
if chunk_spec.instance_of? String then
|
249
|
+
detect {|chunk| chunk.fourcc == "%s" % [ chunk_spec ] }
|
250
|
+
elsif chunk_spec.instance_of? Fixnum or chunk_spec.instance_of? Range then
|
251
|
+
to_a[chunk_spec]
|
252
|
+
else
|
253
|
+
raise ArgumentError , "ListChunk#[] may only accept a String, Fixnum, or Range"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Yields each chunk in the order it appears in the file
|
258
|
+
def each # :yields: chunk
|
259
|
+
@file.pos = @offset + 12
|
260
|
+
while @file.eof? == false && @file.pos < @offset + 8 + @length
|
261
|
+
a_chunk = Chunk.read_chunk(@file)
|
262
|
+
yield a_chunk
|
263
|
+
@file.pos = a_chunk.offset + 8 + a_chunk.length + (a_chunk.length % 2 == 0 ? 0 : 1)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def body # :nodoc:
|
268
|
+
raise NoMethodError , "ListChunk#body is not permitted!"
|
269
|
+
end
|
270
|
+
|
271
|
+
def each_byte
|
272
|
+
raise NoMethodError
|
273
|
+
end
|
274
|
+
|
275
|
+
protected
|
276
|
+
|
277
|
+
def initialize(fp)
|
278
|
+
super(fp)
|
279
|
+
@signature = @file.read(4)
|
280
|
+
end
|
281
|
+
|
282
|
+
end #class ListChunk
|
283
|
+
end #class Riff
|
284
|
+
|
285
|
+
end #module
|
data/lib/riff/bwav.rb
ADDED
data/lib/riff/wav.rb
ADDED
data/test/riff_test.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#--
|
2
|
+
#riff_test.rb -- Test suite for riff.rb -- API for reading generic Microsoft RIFF Files
|
3
|
+
#Copyright (C) 2006 Jamie Hardt
|
4
|
+
|
5
|
+
#This library is free software; you can redistribute it and/or
|
6
|
+
#modify it under the terms of the GNU Lesser General Public
|
7
|
+
#License as published by the Free Software Foundation; either
|
8
|
+
#version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
#This library is distributed in the hope that it will be useful,
|
11
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
#Lesser General Public License for more details.
|
14
|
+
|
15
|
+
#You should have received a copy of the GNU Lesser General Public
|
16
|
+
#License along with this library; if not, write to the Free Software
|
17
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'test/unit'
|
21
|
+
require 'lib/riff/base'
|
22
|
+
|
23
|
+
class Riff_Test < Test::Unit::TestCase
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@test_media_basepath = "test_media/"
|
27
|
+
@test_media = [ ]
|
28
|
+
|
29
|
+
@enumerable_file = "Pop.wav"
|
30
|
+
@malformed_file = "bad.riff"
|
31
|
+
@test_media << @enumerable_file
|
32
|
+
|
33
|
+
@riff_obj_array = []
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_open_close
|
38
|
+
|
39
|
+
@test_media.each do |file|
|
40
|
+
@riff_obj_array << Riff::Base.open(@test_media_basepath + file ,"r")
|
41
|
+
end
|
42
|
+
|
43
|
+
@riff_obj_array.each do |r|
|
44
|
+
assert_instance_of File , r.file
|
45
|
+
r.close
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_root
|
50
|
+
|
51
|
+
@test_media.each do |file|
|
52
|
+
Riff::Base.open(@test_media_basepath + file,"r") do |riff|
|
53
|
+
root_chunk = riff.root_chunk
|
54
|
+
|
55
|
+
assert_equal root_chunk.fourcc , "RIFF"
|
56
|
+
assert_equal root_chunk.signature , "WAVE"
|
57
|
+
assert_instance_of Riff::Base::ListChunk , root_chunk
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_hashing
|
63
|
+
Riff::Base.open(@test_media_basepath + @enumerable_file,"r") do |riff|
|
64
|
+
assert_instance_of Riff::Base::Chunk , riff.root_chunk['bext']
|
65
|
+
assert_instance_of Riff::Base::Chunk , riff.root_chunk['fmt ']
|
66
|
+
assert_equal riff.root_chunk[0].fourcc , 'bext'
|
67
|
+
assert_equal riff.root_chunk[0..1].collect {|c|c.fourcc} , ['bext','fmt ']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_riff_validation
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_simple_read
|
77
|
+
Riff::Base.open(@test_media_basepath + @enumerable_file,"r") do |riff|
|
78
|
+
assert_equal riff.root_chunk.length , 8272
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_each_byte
|
83
|
+
Riff::Base.open(@test_media_basepath + @enumerable_file,"r") do |riff|
|
84
|
+
riff.root_chunk['fmt '].each_byte do |b|
|
85
|
+
assert b >= 0 and b <= 255
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_is_list
|
91
|
+
Riff::Base.open(@test_media_basepath + @enumerable_file, 'r') do |r|
|
92
|
+
assert r.root_chunk.is_list?
|
93
|
+
assert_equal r.root_chunk['bext'].is_list? , false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_riff_enumerable
|
98
|
+
Riff::Base.open(@test_media_basepath + @enumerable_file, 'r') do |r|
|
99
|
+
|
100
|
+
count = 0
|
101
|
+
r.root_chunk.each_with_index do |chunk, i|
|
102
|
+
count +=1
|
103
|
+
case i
|
104
|
+
when 0; assert_equal chunk.fourcc , 'bext'
|
105
|
+
when 1; assert_equal chunk.fourcc , 'fmt '
|
106
|
+
when 2; assert_equal chunk.fourcc , 'minf'
|
107
|
+
when 3; assert_equal chunk.fourcc , 'elm1'
|
108
|
+
when 4; assert_equal chunk.fourcc , 'data'
|
109
|
+
when 5; assert_equal chunk.fourcc , 'regn'
|
110
|
+
when 6; assert_equal chunk.fourcc , 'ovwf'
|
111
|
+
when 7; assert_equal chunk.fourcc , 'umid'
|
112
|
+
when 8; assert(false,"Read too many chunks!")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
assert_equal count , 8
|
116
|
+
|
117
|
+
lengths = r.root_chunk.collect {|c| c.length }
|
118
|
+
|
119
|
+
assert_equal lengths , [ 602 , 16 , 16 , 3410 , 4000 , 92 , 44 , 24]
|
120
|
+
|
121
|
+
assert_equal r.root_chunk.inject(0) {|i , c| c.length + i} , 8204
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
def teardown
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
data/test/wav_test.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
#wav_test.rb -- Test suite for riff/wav
|
3
|
+
# .rb -- API for reading generic Microsoft RIFF Files
|
4
|
+
#Copyright (C) 2006 Jamie Hardt
|
5
|
+
|
6
|
+
#This library is free software; you can redistribute it and/or
|
7
|
+
#modify it under the terms of the GNU Lesser General Public
|
8
|
+
#License as published by the Free Software Foundation; either
|
9
|
+
#version 2.1 of the License, or (at your option) any later version.
|
10
|
+
|
11
|
+
#This library is distributed in the hope that it will be useful,
|
12
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
#Lesser General Public License for more details.
|
15
|
+
|
16
|
+
#You should have received a copy of the GNU Lesser General Public
|
17
|
+
#License along with this library; if not, write to the Free Software
|
18
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
#++
|
20
|
+
|
21
|
+
$: << 'lib/'
|
22
|
+
|
23
|
+
require 'test/unit'
|
24
|
+
require 'lib/riff/wav.rb'
|
25
|
+
|
26
|
+
class Wav_Test < Test::Unit::TestCase
|
27
|
+
|
28
|
+
def setup
|
29
|
+
@test_wav = "Pop.wav"
|
30
|
+
@test_path = "test_media/"
|
31
|
+
@bad_wav = "bad.riff"
|
32
|
+
end
|
33
|
+
|
34
|
+
def teardown
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_validation
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
data/test_media/Pop.wav
ADDED
Binary file
|
data/test_media/bad.riff
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
RIHS 82 eouorf 2u3hro 23
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: riff
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2006-06-03 00:00:00 -07:00
|
8
|
+
summary: "Library for accessing chunks of RIFF (Resource Interchange File Format) files.
|
9
|
+
RIFF is a meta-format which is a common wrapper for multimedia files, such as
|
10
|
+
.wav and .avi files."
|
11
|
+
require_paths:
|
12
|
+
- lib
|
13
|
+
email:
|
14
|
+
homepage: http://riff.rubyforge.org
|
15
|
+
rubyforge_project: riff
|
16
|
+
description:
|
17
|
+
autorequire:
|
18
|
+
default_executable:
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: true
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
-
|
24
|
+
- ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.8.2
|
27
|
+
version:
|
28
|
+
platform: ruby
|
29
|
+
signing_key:
|
30
|
+
cert_chain:
|
31
|
+
authors: []
|
32
|
+
files:
|
33
|
+
- lib/riff/base.rb
|
34
|
+
- lib/riff/bwav.rb
|
35
|
+
- lib/riff/wav.rb
|
36
|
+
- Rakefile
|
37
|
+
- test/riff_test.rb
|
38
|
+
- test/riff_test_suite.rb
|
39
|
+
- test/wav_test.rb
|
40
|
+
- test_media/bad.riff
|
41
|
+
- test_media/Pop.wav
|
42
|
+
- examples/example1.rb
|
43
|
+
- examples/example2.rb
|
44
|
+
test_files:
|
45
|
+
- test/riff_test_suite.rb
|
46
|
+
rdoc_options: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
requirements: []
|
51
|
+
dependencies: []
|