lame 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +20 -0
  2. data/.rspec +3 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +181 -0
  8. data/Rakefile +6 -0
  9. data/docs/id3v2.4.0-structure.txt +731 -0
  10. data/docs/lame-3.99.5.h +1323 -0
  11. data/lame.gemspec +28 -0
  12. data/lib/lame.rb +31 -0
  13. data/lib/lame/buffer.rb +21 -0
  14. data/lib/lame/configuration.rb +228 -0
  15. data/lib/lame/decoder.rb +38 -0
  16. data/lib/lame/decoding/decoded_frame.rb +25 -0
  17. data/lib/lame/decoding/id3_tag_parser.rb +53 -0
  18. data/lib/lame/decoding/mp3_data_header_parser.rb +64 -0
  19. data/lib/lame/decoding/mpeg_audio_frame_finder.rb +46 -0
  20. data/lib/lame/decoding/mpeg_audio_frame_matcher.rb +98 -0
  21. data/lib/lame/decoding/single_frame_decoder.rb +51 -0
  22. data/lib/lame/decoding/stream_decoder.rb +37 -0
  23. data/lib/lame/delegation.rb +68 -0
  24. data/lib/lame/encoder.rb +73 -0
  25. data/lib/lame/encoding/encode_short_buffer.rb +26 -0
  26. data/lib/lame/encoding/flusher.rb +22 -0
  27. data/lib/lame/encoding/id3.rb +46 -0
  28. data/lib/lame/encoding/vbr_info.rb +22 -0
  29. data/lib/lame/error.rb +13 -0
  30. data/lib/lame/ffi.rb +20 -0
  31. data/lib/lame/ffi/decode_flags.rb +19 -0
  32. data/lib/lame/ffi/enums.rb +75 -0
  33. data/lib/lame/ffi/functions.rb +272 -0
  34. data/lib/lame/ffi/global_flags.rb +20 -0
  35. data/lib/lame/ffi/mp3_data.rb +37 -0
  36. data/lib/lame/ffi/version.rb +17 -0
  37. data/lib/lame/version.rb +3 -0
  38. data/spec/buffer_spec.rb +26 -0
  39. data/spec/configuration_spec.rb +391 -0
  40. data/spec/decoder_spec.rb +120 -0
  41. data/spec/decoding/decoded_frame_spec.rb +44 -0
  42. data/spec/decoding/id3_tag_parser_spec.rb +54 -0
  43. data/spec/decoding/mp3_data_header_parser_spec.rb +95 -0
  44. data/spec/decoding/mpeg_audio_frame_finder_spec.rb +50 -0
  45. data/spec/decoding/mpeg_audio_frame_matcher_spec.rb +179 -0
  46. data/spec/decoding/single_frame_decoder_spec.rb +104 -0
  47. data/spec/decoding/stream_decoder_spec.rb +43 -0
  48. data/spec/delegation_spec.rb +146 -0
  49. data/spec/encoder_spec.rb +279 -0
  50. data/spec/encoding/encode_short_buffer_spec.rb +72 -0
  51. data/spec/encoding/flusher_spec.rb +47 -0
  52. data/spec/encoding/id3_spec.rb +106 -0
  53. data/spec/encoding/vbr_info_spec.rb +47 -0
  54. data/spec/ffi/decode_flags_spec.rb +16 -0
  55. data/spec/ffi/encoding_spec.rb +223 -0
  56. data/spec/ffi/global_flags_spec.rb +542 -0
  57. data/spec/ffi/id3tag_spec.rb +135 -0
  58. data/spec/ffi/mp3_data_spec.rb +26 -0
  59. data/spec/files/dies-irae.wav +0 -0
  60. data/spec/integration/decoding_spec.rb +179 -0
  61. data/spec/integration/encoding_spec.rb +126 -0
  62. data/spec/integration/id3_tags_spec.rb +96 -0
  63. data/spec/spec_helper.rb +175 -0
  64. metadata +254 -0
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'wavefile'
3
+ require 'mp3info'
4
+
5
+ describe "ID3 tags", :slow => true do
6
+
7
+ let(:wav_path) { File.expand_path(File.join(File.dirname(__FILE__), '../files/dies-irae.wav')) }
8
+ let(:mp3_id3_path) { File.expand_path(File.join(File.dirname(__FILE__), '../files/dies-irae-id3-raw.mp3')) }
9
+ let(:wav_reader) { WaveFile::Reader.new(wav_path) }
10
+
11
+ it "adds id3v1 tags" do
12
+ encode_wav_file(false)
13
+
14
+ Mp3Info.open(mp3_id3_path) do |info|
15
+ info.hastag1?.should be_true
16
+ info.hastag2?.should be_false
17
+
18
+ tags = info.tag1
19
+ tags["title"].should eql "title"
20
+ tags["artist"].should eql "artist"
21
+ tags["album"].should eql "album"
22
+ tags["year"].should eql 2013
23
+ tags["comments"].should eql "comment"
24
+ tags["tracknum"].should eql 42
25
+ tags["genre_s"].should eql "Rock"
26
+ end
27
+ end
28
+
29
+ it "adds id3v2 tags if configured to" do
30
+ encode_wav_file
31
+
32
+ Mp3Info.open(mp3_id3_path) do |info|
33
+ info.hastag1?.should be_true
34
+ info.hastag2?.should be_true
35
+
36
+ tags = info.tag2
37
+ tags["TIT2"].should eql "title"
38
+ tags["TPE1"].should eql "artist"
39
+ tags["TALB"].should eql "album"
40
+ tags["TYER"].should eql "2013"
41
+ tags["COMM"].should eql "comment"
42
+ tags["TRCK"].should eql "42"
43
+ tags["TCON"].should eql "Rock"
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def encode_wav_file(enable_id3v2 = true)
50
+ encoder = LAME::Encoder.new
51
+
52
+ encoder.configure do |config|
53
+ config.id3.write_automatic = false
54
+ config.id3.v2 = enable_id3v2
55
+ config.id3.title = "title"
56
+ config.id3.artist = "artist"
57
+ config.id3.album = "album"
58
+ config.id3.year = "2013"
59
+ config.id3.comment = "comment"
60
+ config.id3.track = "42"
61
+ config.id3.genre = "Rock"
62
+ end
63
+
64
+ File.open(mp3_id3_path, "wb") do |file|
65
+
66
+ id3v2_size = 0
67
+ encoder.id3v2 do |tag|
68
+ file.write tag
69
+ id3v2_size = tag.size
70
+ end
71
+
72
+ wav_reader.each_buffer(encoder.framesize) do |read_buffer|
73
+ left = read_buffer.samples.map { |s| s[0] }
74
+ right = read_buffer.samples.map { |s| s[1] }
75
+
76
+ encoder.encode_short(left, right) do |mp3|
77
+ file.write mp3
78
+ end
79
+ end
80
+ encoder.flush do |flush_frame|
81
+ file.write(flush_frame)
82
+ end
83
+
84
+ encoder.id3v1 do |tag|
85
+ file.write tag
86
+ end
87
+
88
+ encoder.vbr_frame do |vbr_frame|
89
+ file.seek(id3v2_size)
90
+ file.write(vbr_frame)
91
+ end
92
+
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,175 @@
1
+ if RUBY_DESCRIPTION =~ /\Aruby 1.9/
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start do
10
+ add_filter "/spec/"
11
+ end
12
+ end
13
+
14
+ require 'pry'
15
+ require 'lame'
16
+
17
+ RSpec.configure do |config|
18
+ config.treat_symbols_as_metadata_keys_with_true_values = true
19
+ config.run_all_when_everything_filtered = true
20
+ config.filter_run :focus
21
+ config.order = 'random'
22
+ end
23
+
24
+ def pointer_from_string(str)
25
+ ::FFI::MemoryPointer.from_string(str)
26
+ end
27
+
28
+ module SetterGetter
29
+ def has_getter?(lame, flag)
30
+ lame.respond_to?(:"lame_get_#{flag}")
31
+ end
32
+
33
+ def has_setter?(lame, flag)
34
+ lame.respond_to?(:"lame_set_#{flag}")
35
+ end
36
+
37
+ def set_value(lame, flag)
38
+ lame.send(:"lame_set_#{flag}", @flags_pointer, @value) == return_value
39
+ end
40
+
41
+ def return_value
42
+ defined?(@return) ? @return : 0
43
+ end
44
+
45
+ def has_value?(lame, flag)
46
+ if @value && @value.is_a?(Float)
47
+ actual = actual_value(lame, flag)
48
+ (actual - @value).abs < 0.0001
49
+ elsif @value
50
+ actual_value(lame, flag) == @value
51
+ else
52
+ true
53
+ end
54
+ end
55
+
56
+ def actual_value(lame, flag)
57
+ lame.send(:"lame_get_#{flag}", @flags_pointer)
58
+ end
59
+ end
60
+
61
+ # Validate existence of a getter, setter and the default value.
62
+ RSpec::Matchers.define :have_flag do |expected|
63
+ include SetterGetter
64
+
65
+ chain :for do |flags_pointer|
66
+ @flags_pointer = flags_pointer
67
+ end
68
+
69
+ chain :with_value do |value|
70
+ @value = value
71
+ end
72
+
73
+ match do |actual|
74
+ has_getter?(actual, expected) &&
75
+ has_setter?(actual, expected) &&
76
+ has_value?(actual, expected)
77
+ end
78
+ end
79
+
80
+ # Validate setting a value.
81
+ RSpec::Matchers.define :be_able_to_set do |expected|
82
+ include SetterGetter
83
+
84
+ chain :for do |flags_pointer|
85
+ @flags_pointer = flags_pointer
86
+ end
87
+
88
+ chain :to do |value|
89
+ @value = value
90
+ end
91
+
92
+ chain :and_return do |value|
93
+ @return = value
94
+ end
95
+
96
+ match do |actual|
97
+ set_value(actual, expected) &&
98
+ has_value?(actual, expected)
99
+ end
100
+ end
101
+
102
+ # Validate getting a value.
103
+ RSpec::Matchers.define :have_getter do |expected|
104
+ include SetterGetter
105
+
106
+ chain :for do |flags_pointer|
107
+ @flags_pointer = flags_pointer
108
+ end
109
+
110
+ chain :with_value do |value|
111
+ @value = value
112
+ end
113
+
114
+ match do |actual|
115
+ has_getter?(actual, expected) &&
116
+ has_value?(actual, expected)
117
+ end
118
+
119
+ failure_message_for_should do |actual|
120
+ if !has_getter?(actual, expected)
121
+ "expected that #{actual} would have a getter for field :#{expected}"
122
+ elsif @value && !has_value?(actual, expected)
123
+ actual_value = actual_value(actual, expected)
124
+ "expected field :#{expected} to have a value of #{@value}, but got #{actual_value}"
125
+ end
126
+ end
127
+ end
128
+
129
+ # Validate delegation to global_flags.
130
+ RSpec::Matchers.define :delegate do |from|
131
+ include SetterGetter
132
+
133
+ chain :to do |target|
134
+ @target = target
135
+ end
136
+
137
+ match do |subject|
138
+ @from = from
139
+ has_setter?(LAME, target) &&
140
+ delegates_setter? &&
141
+ has_getter?(LAME, target) &&
142
+ delegates_getter?
143
+ end
144
+
145
+ def delegates_setter?
146
+ LAME.should_receive(:"lame_set_#{target}").with(subject.global_flags, anything)
147
+ subject.send(:"#{from}=", double)
148
+ true
149
+ rescue => e
150
+ # TODO: save raised exception for better failure message
151
+ false
152
+ end
153
+
154
+ def delegates_getter?
155
+ LAME.should_receive(:"lame_get_#{target}").with(subject.global_flags)
156
+ subject.send(:"#{from}")
157
+ true
158
+ rescue => e
159
+ # TODO: save raised exception for better failure message
160
+ false
161
+ end
162
+
163
+ failure_message_for_should do |actual|
164
+ "expected #{subject.class} to delegate :#{from} to LAME.lame_set_#{target}"
165
+ end
166
+
167
+ def target
168
+ @target || from
169
+ end
170
+
171
+ def from
172
+ @from
173
+ end
174
+
175
+ end
metadata ADDED
@@ -0,0 +1,254 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lame
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Roel van Dijk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ type: :runtime
16
+ prerelease: false
17
+ name: ffi
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ none: false
24
+ requirement: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ type: :development
32
+ prerelease: false
33
+ name: rake
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ none: false
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ type: :development
48
+ prerelease: false
49
+ name: rspec
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ none: false
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
63
+ type: :development
64
+ prerelease: false
65
+ name: pry
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ none: false
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ none: false
78
+ - !ruby/object:Gem::Dependency
79
+ type: :development
80
+ prerelease: false
81
+ name: wavefile
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ none: false
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ none: false
94
+ - !ruby/object:Gem::Dependency
95
+ type: :development
96
+ prerelease: false
97
+ name: ruby-mp3info
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ none: false
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ none: false
110
+ - !ruby/object:Gem::Dependency
111
+ type: :development
112
+ prerelease: false
113
+ name: coveralls
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ none: false
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ none: false
126
+ description: FFI powered library for the LAME MP3 encoder.
127
+ email:
128
+ - roel@rustradio.org
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - .rvmrc
136
+ - .travis.yml
137
+ - Gemfile
138
+ - LICENSE.txt
139
+ - README.md
140
+ - Rakefile
141
+ - docs/id3v2.4.0-structure.txt
142
+ - docs/lame-3.99.5.h
143
+ - lame.gemspec
144
+ - lib/lame.rb
145
+ - lib/lame/buffer.rb
146
+ - lib/lame/configuration.rb
147
+ - lib/lame/decoder.rb
148
+ - lib/lame/decoding/decoded_frame.rb
149
+ - lib/lame/decoding/id3_tag_parser.rb
150
+ - lib/lame/decoding/mp3_data_header_parser.rb
151
+ - lib/lame/decoding/mpeg_audio_frame_finder.rb
152
+ - lib/lame/decoding/mpeg_audio_frame_matcher.rb
153
+ - lib/lame/decoding/single_frame_decoder.rb
154
+ - lib/lame/decoding/stream_decoder.rb
155
+ - lib/lame/delegation.rb
156
+ - lib/lame/encoder.rb
157
+ - lib/lame/encoding/encode_short_buffer.rb
158
+ - lib/lame/encoding/flusher.rb
159
+ - lib/lame/encoding/id3.rb
160
+ - lib/lame/encoding/vbr_info.rb
161
+ - lib/lame/error.rb
162
+ - lib/lame/ffi.rb
163
+ - lib/lame/ffi/decode_flags.rb
164
+ - lib/lame/ffi/enums.rb
165
+ - lib/lame/ffi/functions.rb
166
+ - lib/lame/ffi/global_flags.rb
167
+ - lib/lame/ffi/mp3_data.rb
168
+ - lib/lame/ffi/version.rb
169
+ - lib/lame/version.rb
170
+ - spec/buffer_spec.rb
171
+ - spec/configuration_spec.rb
172
+ - spec/decoder_spec.rb
173
+ - spec/decoding/decoded_frame_spec.rb
174
+ - spec/decoding/id3_tag_parser_spec.rb
175
+ - spec/decoding/mp3_data_header_parser_spec.rb
176
+ - spec/decoding/mpeg_audio_frame_finder_spec.rb
177
+ - spec/decoding/mpeg_audio_frame_matcher_spec.rb
178
+ - spec/decoding/single_frame_decoder_spec.rb
179
+ - spec/decoding/stream_decoder_spec.rb
180
+ - spec/delegation_spec.rb
181
+ - spec/encoder_spec.rb
182
+ - spec/encoding/encode_short_buffer_spec.rb
183
+ - spec/encoding/flusher_spec.rb
184
+ - spec/encoding/id3_spec.rb
185
+ - spec/encoding/vbr_info_spec.rb
186
+ - spec/ffi/decode_flags_spec.rb
187
+ - spec/ffi/encoding_spec.rb
188
+ - spec/ffi/global_flags_spec.rb
189
+ - spec/ffi/id3tag_spec.rb
190
+ - spec/ffi/mp3_data_spec.rb
191
+ - spec/files/dies-irae-cli-id3v2.mp3
192
+ - spec/files/dies-irae.wav
193
+ - spec/integration/decoding_spec.rb
194
+ - spec/integration/encoding_spec.rb
195
+ - spec/integration/id3_tags_spec.rb
196
+ - spec/spec_helper.rb
197
+ homepage: http://github.com/rdvdijk/lame
198
+ licenses: []
199
+ post_install_message:
200
+ rdoc_options: []
201
+ require_paths:
202
+ - lib
203
+ required_ruby_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ! '>='
206
+ - !ruby/object:Gem::Version
207
+ hash: 3287054386049799145
208
+ segments:
209
+ - 0
210
+ version: '0'
211
+ none: false
212
+ required_rubygems_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ! '>='
215
+ - !ruby/object:Gem::Version
216
+ hash: 3287054386049799145
217
+ segments:
218
+ - 0
219
+ version: '0'
220
+ none: false
221
+ requirements: []
222
+ rubyforge_project:
223
+ rubygems_version: 1.8.25
224
+ signing_key:
225
+ specification_version: 3
226
+ summary: Easily encode MP3 files using the LAME MP3 encoder.
227
+ test_files:
228
+ - spec/buffer_spec.rb
229
+ - spec/configuration_spec.rb
230
+ - spec/decoder_spec.rb
231
+ - spec/decoding/decoded_frame_spec.rb
232
+ - spec/decoding/id3_tag_parser_spec.rb
233
+ - spec/decoding/mp3_data_header_parser_spec.rb
234
+ - spec/decoding/mpeg_audio_frame_finder_spec.rb
235
+ - spec/decoding/mpeg_audio_frame_matcher_spec.rb
236
+ - spec/decoding/single_frame_decoder_spec.rb
237
+ - spec/decoding/stream_decoder_spec.rb
238
+ - spec/delegation_spec.rb
239
+ - spec/encoder_spec.rb
240
+ - spec/encoding/encode_short_buffer_spec.rb
241
+ - spec/encoding/flusher_spec.rb
242
+ - spec/encoding/id3_spec.rb
243
+ - spec/encoding/vbr_info_spec.rb
244
+ - spec/ffi/decode_flags_spec.rb
245
+ - spec/ffi/encoding_spec.rb
246
+ - spec/ffi/global_flags_spec.rb
247
+ - spec/ffi/id3tag_spec.rb
248
+ - spec/ffi/mp3_data_spec.rb
249
+ - spec/files/dies-irae-cli-id3v2.mp3
250
+ - spec/files/dies-irae.wav
251
+ - spec/integration/decoding_spec.rb
252
+ - spec/integration/encoding_spec.rb
253
+ - spec/integration/id3_tags_spec.rb
254
+ - spec/spec_helper.rb