ruby-cafinfo 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/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ === 0.1 / 2009-03-12
2
+
3
+ * initial release: contains basic support for audio_description, data, free and magick cookie chunks.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Oleguer Huguet Ibars
2
+
3
+ The MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,76 @@
1
+ ruby-cafinfo
2
+
3
+ by Oleguer Huguet Ibars
4
+ * http://rubyforge.org/projects/ruby-cafinfo
5
+ * git repository: git://rubyforge.org/ruby-cafinfo.git
6
+
7
+ == DESCRIPTION:
8
+
9
+ A ruby library to retrieve information of CAF (Core Audio Format) files, heavily inspired by the excellent ruby-mp3info[http://ruby-mp3info.rubyforge.org/].
10
+
11
+ From the CAF format specification:
12
+
13
+ "Apple's Core Audio Format (CAF) is a file format for storing and transporting digital
14
+ audio data. It simplifies the management and manipulation of many types of audio data
15
+ without the file-size limitations of other audio file formats."
16
+
17
+ Specs for CAF format can be found here[http://developer.apple.com/DOCUMENTATION/MusicAudio/Reference/CAFSpec/CAF_intro/CAF_intro.html].
18
+
19
+ == FEATURES:
20
+
21
+ * written in pure ruby
22
+ * read low-level informations like bitrate, length, samplerate, etc...
23
+ * only some chunk types are recognized (Audio Description, Data, Free, Magick Cookie)
24
+
25
+ == SYNOPSIS:
26
+
27
+ Using as a lib is easy:
28
+
29
+ require "cafinfo"
30
+ # read and display info
31
+ CafInfo.open("myfile.caf") do |cafinfo|
32
+ puts cafinfo
33
+ end
34
+
35
+ # read and display some attributes
36
+ CafInfo.open("myfile.caf") do |caf|
37
+ puts caf.length
38
+ puts caf.samplerate
39
+ puts caf.format
40
+ end
41
+
42
+ # extract payload audio data from a (small) CAF and write to another file
43
+ audio_pos, audio_length = CafInfo.open("myfile.caf") { |caf| caf.audio_content }
44
+ File.open("myfile.caf", "rb") do |caf_file|
45
+ File.open("myaudio.data", "wb") do |f|
46
+ caf_file.seek(audio_pos)
47
+ data = caf_file.read(audio_length)
48
+ f.write(data)
49
+ end
50
+ end
51
+
52
+ # extract payload audio data from an arbitrarily large CAF and write
53
+ # to another file, considering that data chunk may not be at the end
54
+ # of caf file
55
+ audio_pos, audio_length = CafInfo.open("myfile.caf") { |caf| caf.audio_content }
56
+ File.open("myfile.caf", "rb") do |caf_file|
57
+ File.open("myaudio-buffered.data", "wb") do |f|
58
+ caf_file.seek(audio_pos)
59
+ while buffer = caf_file.read([4096, audio_length].min) and buffer.size > 0
60
+ f.write(buffer)
61
+ audio_length -= buffer.size
62
+ end
63
+ end
64
+ end
65
+
66
+ == INSTALL:
67
+
68
+ # gem install ruby-cafinfo
69
+
70
+ == LICENSE:
71
+
72
+ MIT license
73
+
74
+ == TODO:
75
+
76
+ * support for other chunk types
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+
8
+ spec = Gem::Specification.new do |s|
9
+ s.name = 'ruby-cafinfo'
10
+ s.version = '0.1'
11
+ s.has_rdoc = true
12
+ s.extra_rdoc_files = ['README', 'LICENSE', 'CHANGELOG']
13
+ s.summary = 'ruby-cafinfo is a ruby library to retrieve low level informations on CAF files'
14
+ s.description = s.summary
15
+ s.author = 'Oleguer Huguet Ibars'
16
+ s.email = 'olegueret@rubyforge.org'
17
+ # s.executables = ['your_executable_here']
18
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
19
+ s.require_path = "lib"
20
+ #s.bindir = "bin"
21
+ s.add_dependency 'float-formats', '>=0.1.1'
22
+ s.rubyforge_project = 'ruby-cafinfo'
23
+ s.homepage = 'http://ruby-cafinfo.rubyforge.org'
24
+ end
25
+
26
+ Rake::GemPackageTask.new(spec) do |p|
27
+ p.gem_spec = spec
28
+ p.need_tar = true
29
+ p.need_zip = true
30
+ end
31
+
32
+ Rake::RDocTask.new do |rdoc|
33
+ files =['README', 'LICENSE', 'CHANGELOG', 'lib/**/*.rb']
34
+ rdoc.rdoc_files.add(files)
35
+ rdoc.main = "README" # page to start on
36
+ rdoc.title = "ruby-cafinfo Docs"
37
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
38
+ rdoc.options << '--line-numbers'
39
+ end
40
+
41
+ Rake::TestTask.new do |t|
42
+ t.test_files = FileList['test/**/*.rb']
43
+ end
data/lib/caf/chunk.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'caf/chunk/base'
2
+
3
+ module Caf
4
+ module Chunk
5
+ def self.available_chunk_types
6
+ @available_chunk_types ||= {}
7
+ end
8
+
9
+ def self.build(chunk_header)
10
+ klass = available_chunk_types[(chunk_header[:chunk_type] || "").downcase]
11
+ klass = Base if klass.nil?
12
+ klass.new(chunk_header)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,57 @@
1
+ require 'caf/chunk/base'
2
+ require 'caf/chunk/helper'
3
+ require 'caf/errors'
4
+
5
+ module Caf::Chunk
6
+ include Helper
7
+
8
+ class AudioDescription < Base
9
+
10
+ implements 'desc'
11
+
12
+ attr_accessor :samplerate, :format_id, :format_flags, :bytes_per_packet,
13
+ :frames_per_packet, :channels_per_frame, :bits_per_channel
14
+
15
+ def initialize(chunk_header)
16
+ super chunk_header
17
+ end
18
+
19
+ def to_s
20
+ "#{chunk_type} (audio description chunk):\n"+
21
+ " -samplerate: #{samplerate}\n"+
22
+ " -format ID: #{format_id}\n"+
23
+ " -format flags: #{format_flags}\n"+
24
+ " -bytes per packet: #{bytes_per_packet}\n"+
25
+ " -frames per packet: #{frames_per_packet}\n"+
26
+ " -channels per frame: #{channels_per_frame}\n"+
27
+ " -bits per channel: #{bits_per_channel}\n"
28
+ end
29
+
30
+ def validate
31
+ raise(Caf::Error, "invalid audio description chunk: sample rate cannot be 0") if samplerate == 0
32
+ raise(Caf::Error, "invalid audio description chunk: format ID cannot be 0") if format_id == 0
33
+ raise(Caf::Error, "invalid audio description chunk: channels per frame cannot be 0") if channels_per_frame == 0
34
+ end
35
+
36
+ def fields_size
37
+ 32
38
+ end
39
+
40
+ def read_data(file)
41
+ data = file.read(self.fields_size)
42
+ raise(Caf::Error, "chunk data too short: #{self}") if file.eof?
43
+
44
+ @samplerate = Helper.read_double(data)
45
+ @format_id = Helper.read_chars(4, data, 8)
46
+ @format_flags = Helper.read_int(data, 12)
47
+ @bytes_per_packet = Helper.read_int(data, 16)
48
+ @frames_per_packet = Helper.read_int(data, 20)
49
+ @channels_per_frame = Helper.read_int(data, 24)
50
+ @bits_per_channel = Helper.read_int(data, 28)
51
+
52
+ self.validate
53
+
54
+ data.size
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ require 'caf/chunk'
2
+ require 'caf/chunk/helper'
3
+ require 'caf/errors'
4
+
5
+ module Caf::Chunk
6
+ include Helper
7
+
8
+ class Base
9
+
10
+ def self.implements(chunk_type)
11
+ Caf::Chunk.available_chunk_types[chunk_type] = self
12
+ end
13
+
14
+ attr_reader :chunk_type, :chunk_size
15
+
16
+ def initialize(chunk_header)
17
+ @chunk_type = chunk_header[:chunk_type]
18
+ @chunk_size = chunk_header[:chunk_size]
19
+ end
20
+
21
+ def to_s
22
+ "#{chunk_type} (unknown chunk)"
23
+ end
24
+
25
+ def validate
26
+ raise(Caf::Error, "chunk must implement validate method: #{chunk_type}") unless self.instance_of?(Base)
27
+ true
28
+ end
29
+
30
+ def fields_size
31
+ raise(Caf::Error, "chunk must implement fields_size method: #{chunk_type}") unless self.instance_of?(Base)
32
+ end
33
+
34
+ def read_data(file)
35
+ file.seek(chunk_size, IO::SEEK_CUR) unless chunk_size == -1
36
+ end
37
+
38
+ def check_type_and_size(expected_klass, expected_chunk_type)
39
+ raise(Caf::Error, "expected an #{expected_chunk_type} chunk") unless self.instance_of?(expected_klass)
40
+ raise(Caf::Error, "corrupted chunk: wrong size (expected #{fields_size}, got #{chunk_size}") if fields_size != chunk_size
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,47 @@
1
+ require 'caf/chunk/base'
2
+ require 'caf/chunk/helper'
3
+ require 'caf/errors'
4
+
5
+ module Caf::Chunk
6
+ include Helper
7
+
8
+ class Data < Base
9
+
10
+ implements 'data'
11
+
12
+ attr_accessor :edit_count, :size, :position
13
+
14
+ def initialize(chunk_header)
15
+ super chunk_header
16
+ end
17
+
18
+ def to_s
19
+ "#{chunk_type} (data chunk):\n"+
20
+ " -edit count: #{edit_count}\n" +
21
+ " -data size: #{size}\n" +
22
+ " -data position: #{position}\n"
23
+ end
24
+
25
+ def validate
26
+ end
27
+
28
+ def fields_size
29
+ raise(Caf::Error, "not implemented")
30
+ end
31
+
32
+ def read_data(file)
33
+ edit = file.read(4)
34
+ @edit_count = (edit.getbyte(0) << 32) + (edit.getbyte(1) << 16) + (edit.getbyte(2) << 8) + edit.getbyte(3)
35
+ @position = file.pos
36
+ unless chunk_size == -1
37
+ @size = chunk_size - 4 # 4 bytes are from edit_count field
38
+ file.seek(@size, IO::SEEK_CUR)
39
+ else
40
+ file.seek(0, IO::SEEK_END)
41
+ @size = file.pos - @position
42
+ # TODO should update chunk_size field with @size + 4 if file is writable
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ require 'caf/chunk/base'
2
+ require 'caf/errors'
3
+
4
+ module Caf::Chunk
5
+ include Helper
6
+
7
+ class Free < Base
8
+
9
+ implements 'free'
10
+
11
+ def to_s
12
+ "#{chunk_type} (free chunk)"
13
+ end
14
+
15
+ def validate
16
+ true
17
+ end
18
+
19
+ def fields_size
20
+ raise(Caf::Error, "not implemented")
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'float-formats'
3
+ include FltPnt
4
+
5
+ module Caf::Chunk
6
+ module Helper
7
+
8
+ BIT_SHIFTS_8 = [64, 56, 48, 40, 32, 24, 16, 8]
9
+
10
+ def self.read_bytes(number, data, offset = 0)
11
+ buffer = 0
12
+ number_minus = number - 1
13
+ number_minus.downto(0) do |i|
14
+ buffer += (data.getbyte(offset + number_minus - i) << (8 * i))
15
+ end
16
+ buffer
17
+ end
18
+
19
+ def self.read_chars(number, data, offset = 0)
20
+ buffer = ''
21
+ 0.upto(number-1) { |i| buffer += data.getbyte(offset+i).chr }
22
+ buffer
23
+ end
24
+
25
+ def self.read_double(data, offset = 0)
26
+ num = read_bytes(8, data, offset)
27
+ IEEE_binary64.from_bits_integer(num).to_number(Float)
28
+ end
29
+
30
+ def self.read_int(data, offset = 0)
31
+ read_bytes(4, data, offset).to_i
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ require 'caf/chunk/base'
2
+ require 'caf/errors'
3
+
4
+ module Caf::Chunk
5
+ include Helper
6
+
7
+ class MagicCookie < Base
8
+
9
+ implements 'kuki'
10
+
11
+ attr_reader :size, :position #, :data
12
+
13
+ def to_s
14
+ "#{chunk_type} (magic cookie chunk)\n" +
15
+ " -cookie size: #{size}\n" +
16
+ " -cookie position: #{position}\n"
17
+ end
18
+
19
+ def validate
20
+ true
21
+ end
22
+
23
+ def fields_size
24
+ raise(Caf::Error, "not implemented")
25
+ end
26
+
27
+ def read_data(file)
28
+ @size = chunk_size
29
+ @position = file.pos
30
+ #@data = file.read(chunk_size)
31
+ super(file)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ require 'caf/chunk/base'
2
+ require "caf/chunk/audio_description"
3
+ require 'caf/chunk/data'
4
+ require "caf/chunk/free"
5
+ require "caf/chunk/magic_cookie"
data/lib/caf/errors.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Caf
2
+ # Raised on any kind of error related to ruby-cafinfo
3
+ class Error < StandardError ; end
4
+ end
@@ -0,0 +1,41 @@
1
+ class CafInfo
2
+ module HashKeys #:nodoc:
3
+ ### lets you specify hash["key"] as hash.key
4
+ ### this came from CodingInRuby on RubyGarden
5
+ ### http://www.rubygarden.org/ruby?CodingInRuby
6
+ def method_missing(meth,*args)
7
+ m = meth.id2name
8
+ if /=$/ =~ m
9
+ self[m.chop] = (args.length<2 ? args[0] : args)
10
+ else
11
+ self[m]
12
+ end
13
+ end
14
+ end
15
+
16
+ class ::String
17
+ if RUBY_VERSION < "1.9.0"
18
+ alias getbyte []
19
+ else
20
+ def getbyte(i)
21
+ self[i].ord
22
+ end
23
+ end
24
+ end
25
+
26
+ module CafFileMethods #:nodoc:
27
+ if RUBY_VERSION < "1.9.0"
28
+ def getbyte
29
+ getc
30
+ end
31
+ end
32
+
33
+ def get32bits
34
+ (getbyte << 24) + (getbyte << 16) + (getbyte << 8) + getbyte
35
+ end
36
+
37
+ def get_syncsafe
38
+ (getbyte << 21) + (getbyte << 14) + (getbyte << 7) + getbyte
39
+ end
40
+ end
41
+ end
data/lib/cafinfo.rb ADDED
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env ruby
2
+ # coding:utf-8
3
+ # License:: Mit
4
+ # Author:: Oleguer Huguet Ibars (mailto:oleguer_DOT_huguet_AT__gmail_DOT_com)
5
+ # Website:: http://ruby-cafinfo.rubyforge.org/
6
+
7
+ require "fileutils"
8
+
9
+ $:.unshift "#{File.dirname(__FILE__)}"
10
+ require 'caf/extension_modules'
11
+ require 'caf/errors'
12
+ require 'caf/chunk/types'
13
+
14
+ # ruby -d to display debugging infos
15
+
16
+ class CafInfo
17
+
18
+ VERSION = "0.1"
19
+
20
+ # the original filename
21
+ attr_reader(:filename)
22
+
23
+ # duration in seconds of audio
24
+ attr_reader(:length)
25
+
26
+ # the number of sample frames per second of the data
27
+ attr_reader(:samplerate)
28
+
29
+ # a four-character code indicating the general kind of data in the stream
30
+ attr_reader(:format)
31
+
32
+ # flags specific to each format
33
+ attr_reader(:format_flags)
34
+
35
+ # the number of bytes in a packet of data.
36
+ attr_reader(:bytes_per_packet)
37
+
38
+ # the number of sample frames in each packet of data
39
+ attr_reader(:frames_per_packet)
40
+
41
+ # the number of channels in each frame of data
42
+ attr_reader(:channels_per_frame)
43
+
44
+ # the number of bits of sample data for each channel in a frame of data.
45
+ # 0 if the data format does not contain separate samples for each channel (for instance any compressed format)
46
+ attr_reader(:bits_per_channel)
47
+
48
+ # variable bitrate => true or false
49
+ attr_reader(:vbr)
50
+
51
+ # variable frame rate => true or false
52
+ attr_reader(:vfr)
53
+
54
+ # Instantiate CafInfo object with name +filename+.
55
+ def initialize(filename)
56
+ warn("#{self.class}::new() does not take block; use #{self.class}::open() instead") if block_given?
57
+ @filename = filename
58
+ @header = {}
59
+ reload
60
+ end
61
+
62
+ # reload (or load for the first time) the file from disk
63
+ def reload
64
+ raise(Caf::Error, "empty file") unless File.size?(@filename)
65
+
66
+ @file = File.new(filename, "rb")
67
+ @file.extend(CafFileMethods)
68
+
69
+ @chunks = {}
70
+
71
+ begin
72
+ @header = read_file_header
73
+ chunk = read_audio_description_chunk
74
+ @chunks[chunk.chunk_type.to_sym] = chunk
75
+ puts "Found chunk: #{@chunks[chunk.chunk_type.to_sym]}" if $DEBUG
76
+
77
+ until @file.eof? do
78
+ chunk = read_chunk_header
79
+ chunk.read_data(@file)
80
+ @chunks[chunk.chunk_type.to_sym] = chunk
81
+
82
+ puts "Found chunk: #{chunk}" if $DEBUG
83
+ end
84
+ ensure
85
+ @file.close
86
+ end
87
+
88
+ raise(Caf::Error, "data chunk not found") if @chunks[:data].nil?
89
+ @length = (@frames_per_packet * @chunks[:data].size) / (@samplerate * @bytes_per_packet)
90
+ end
91
+
92
+ # "block version" of CafInfo::new()
93
+ def self.open(*params)
94
+ m = self.new(*params)
95
+ ret = nil
96
+ if block_given?
97
+ begin
98
+ ret = yield(m)
99
+ ensure
100
+ m.close
101
+ end
102
+ else
103
+ ret = m
104
+ end
105
+ ret
106
+ end
107
+
108
+ # write to another filename at close()
109
+ def rename(new_filename)
110
+ @filename = new_filename
111
+ end
112
+
113
+ # this method returns the "audio-only" data boundaries of the file,
114
+ # i.e. data chunk content. Returned value is an array
115
+ # [position_in_the_file, length_of_the_data]
116
+ def audio_content
117
+ [@chunks[:data].position, @chunks[:data].size]
118
+ end
119
+
120
+ # Flush pending modifications and close the file
121
+ def close
122
+ puts "close" if $DEBUG
123
+ end
124
+
125
+ # close and reopen the file, i.e. commit changes to disk and
126
+ # reload it
127
+ def flush
128
+ close
129
+ reload
130
+ end
131
+
132
+ # inspect inside CafInfo
133
+ def to_s
134
+ s = "CAF (version #{@header[:file_version]}) #{@format} #{"VFR " if @vfr}#{@vbr ? "VBR" : "CBR"} #{@samplerate} Hz length #{@length} sec."
135
+ s << ""
136
+ s
137
+ end
138
+
139
+ private
140
+
141
+ ### reads through @file to find its header
142
+ def read_file_header
143
+ header = {}
144
+ head = @file.read(8)
145
+ raise(Caf::Error, "file header too short") if @file.eof?
146
+ raise(Caf::Error, "not a CAF file") unless head.match(/^caff/)
147
+
148
+ header[:file_version] = (head.getbyte(4) << 8) + head.getbyte(5)
149
+ raise(Caf::Error, "invalid CAF file version (supported only version 1)") if header[:file_version] != 1
150
+
151
+ header[:file_flags] = (head.getbyte(6) << 8) + head.getbyte(7)
152
+ raise(Caf::Error, "invalid CAF file flags") if header[:file_flags] != 0
153
+ header
154
+ end
155
+
156
+ def read_chunk_header
157
+ header = {}
158
+ head = @file.read(12)
159
+
160
+ raise(Caf::Error, "chunk header too short: #{head.size}") if head && head.size < 12
161
+
162
+ header[:chunk_type] = head.getbyte(0).chr + head.getbyte(1).chr + head.getbyte(2).chr + head.getbyte(3).chr
163
+ header[:chunk_size] = (head.getbyte(4) << 512) + (head.getbyte(5) << 256) + (head.getbyte(6) << 128) + (head.getbyte(7) << 64)+
164
+ (head.getbyte(8) << 32) + (head.getbyte(9) << 16) + (head.getbyte(10) << 8) + head.getbyte(11)
165
+ Caf::Chunk.build(header)
166
+ end
167
+
168
+ def read_audio_description_chunk
169
+ chunk = read_chunk_header
170
+ chunk.check_type_and_size(Caf::Chunk::AudioDescription, 'audio description')
171
+
172
+ chunk.read_data(@file)
173
+
174
+ @vbr = chunk.bytes_per_packet == 0
175
+ @vfr = chunk.frames_per_packet == 0
176
+ @samplerate = chunk.samplerate.to_i
177
+ @format = chunk.format_id
178
+ @format_flags = chunk.format_flags
179
+ @bytes_per_packet = chunk.bytes_per_packet
180
+ @frames_per_packet = chunk.frames_per_packet
181
+ @channels_per_frame = chunk.channels_per_frame
182
+ @bits_per_channel = chunk.bits_per_channel
183
+
184
+ chunk
185
+ end
186
+
187
+ end
188
+
189
+ if $0 == __FILE__
190
+ error = 0
191
+ while filename = ARGV.shift
192
+ begin
193
+ info = CafInfo.new(filename)
194
+ puts filename
195
+ puts info
196
+ rescue Caf::Error => e
197
+ puts "#{filename}\nERROR: #{e}"
198
+ error = 1
199
+ end
200
+ puts
201
+ end
202
+ exit(error)
203
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-cafinfo
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Oleguer Huguet Ibars
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-19 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: float-formats
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ description: ruby-cafinfo is a ruby library to retrieve low level informations on CAF files
26
+ email: olegueret@rubyforge.org
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ - CHANGELOG
35
+ files:
36
+ - LICENSE
37
+ - README
38
+ - Rakefile
39
+ - lib/cafinfo.rb
40
+ - lib/caf
41
+ - lib/caf/chunk
42
+ - lib/caf/chunk/audio_description.rb
43
+ - lib/caf/chunk/magic_cookie.rb
44
+ - lib/caf/chunk/base.rb
45
+ - lib/caf/chunk/free.rb
46
+ - lib/caf/chunk/types.rb
47
+ - lib/caf/chunk/data.rb
48
+ - lib/caf/chunk/helper.rb
49
+ - lib/caf/extension_modules.rb
50
+ - lib/caf/errors.rb
51
+ - lib/caf/chunk.rb
52
+ - CHANGELOG
53
+ has_rdoc: true
54
+ homepage: http://ruby-cafinfo.rubyforge.org
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project: ruby-cafinfo
75
+ rubygems_version: 1.3.1
76
+ signing_key:
77
+ specification_version: 2
78
+ summary: ruby-cafinfo is a ruby library to retrieve low level informations on CAF files
79
+ test_files: []
80
+