icanhasaudio 0.0.3 → 0.1.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.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.1.0
2
+
3
+ * 1 major enhancement
4
+ * Added MPEG Encoder
5
+
1
6
  == 0.0.3
2
7
  * 1 minor enhancement
3
8
  * Fixed extconf to be a little more smart.
data/Manifest.txt CHANGED
@@ -4,6 +4,7 @@ Manifest.txt
4
4
  README.txt
5
5
  Rakefile
6
6
  examples/decoder.rb
7
+ examples/encoder.rb
7
8
  examples/kexp.rb
8
9
  ext/decoder.c
9
10
  ext/decoder.h
@@ -11,10 +12,16 @@ ext/extconf.rb
11
12
  ext/get_audio.c
12
13
  ext/get_audio.h
13
14
  ext/icanhasaudio.c
15
+ ext/icanhasaudio.h
16
+ ext/mpeg_encoder.c
17
+ ext/mpeg_encoder.h
14
18
  ext/rb_ogg.c
15
19
  ext/rb_wav.c
16
20
  ext/rb_wav.h
17
21
  ext/syncword.c
18
22
  ext/syncword.h
19
23
  lib/icanhasaudio/mpeg.rb
24
+ lib/icanhasaudio/mpeg/encoder.rb
20
25
  lib/icanhasaudio/ogg.rb
26
+ test/assets/testcase.wav
27
+ test/test_mpeg_encoder.rb
data/README.txt CHANGED
@@ -5,7 +5,8 @@
5
5
  == DESCRIPTION. LULZ
6
6
 
7
7
  Hai! icanhasaudio? is an interface to lame for decoding ur MP3s. I iz in ur
8
- computer. Decodin ur mp3s. Whatevs! I also decodin ur OGGz!
8
+ computer. Decodin ur mp3s. Whatevs! I also decodin ur OGGz! I kin also
9
+ encodin' ur WAV and AIFF to mp3z!
9
10
 
10
11
  == SYNOPSYS ROFLOL
11
12
 
@@ -23,15 +24,27 @@ Or even smaller:
23
24
  reader = Audio::OGG::Decoder.new
24
25
  reader.decode(File.open(ARGV[0], 'rb'), File.open(ARGV[1], 'wb'))
25
26
 
27
+ Encoder!!!!!! LOL
28
+
29
+ writer = Audio::MPEG::Encoder.new
30
+ File.open(ARGV[0]), 'rb') { |wav_lol|
31
+ File.open(ARGV[1]), 'wb+') { |mp3_lol|
32
+ writer.encode(wav_lol, mp3_lol)
33
+ }
34
+ }
35
+
26
36
  == PROBLEMS
27
37
 
28
- Currently only decodes MP3/OGG data. Plus many other problems.... YMMV. LOL.
38
+ Currently only decodes MP3/OGG data. Also encodes WAV/AIFF to mp3. Plus many
39
+ other problems.... YMMV. LOL.
29
40
  Not laugh plz!
30
41
 
31
42
  == DEPENDENSEEZ
32
43
 
33
44
  Make sure lame is installed on ur 'puter. Also ogg and vorbisfile!
34
45
 
46
+ # port install libvorbis vorbis-tools lame
47
+
35
48
  == CREDITZ
36
49
 
37
50
  Thanx Ryan for mah name! Also, most of this code was taken from the lame
data/Rakefile CHANGED
@@ -2,7 +2,9 @@ require 'hoe'
2
2
 
3
3
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
4
4
 
5
- Hoe.new('icanhasaudio', '0.0.3') do |p|
5
+ kind = Config::CONFIG["DLEXT"]
6
+
7
+ Hoe.new('icanhasaudio', '0.1.0') do |p|
6
8
  p.rubyforge_name = 'seattlerb'
7
9
  p.author = 'Aaron Patterson'
8
10
  p.email = 'aaronp@rubyforge.org'
@@ -11,5 +13,18 @@ Hoe.new('icanhasaudio', '0.0.3') do |p|
11
13
  p.url = p.paragraphs_of('README.txt', 1).first.strip
12
14
  p.changes = p.paragraphs_of('History.txt', 0..2).join("\n\n")
13
15
  p.spec_extras = { :extensions => ['ext/extconf.rb'] }
16
+ p.clean_globs = ["ext/Makefile", "ext/*.{o,so,bundle,log}"]
17
+ end
18
+
19
+ Rake::Task[:test].prerequisites << :extension
20
+
21
+ desc "I can haz binary"
22
+ task :extension => ["ext/icanhasaudio.#{kind}"]
23
+
24
+ file "ext/Makefile" => "ext/extconf.rb" do
25
+ Dir.chdir("ext") { ruby "extconf.rb" }
14
26
  end
15
27
 
28
+ file "ext/icanhasaudio.#{kind}" => FileList["ext/Makefile", "ext/*.{c,h}"] do
29
+ Dir.chdir("ext") { sh "make" }
30
+ end
@@ -0,0 +1,28 @@
1
+ require 'icanhasaudio'
2
+
3
+ include Audio::MPEG
4
+
5
+ writer = Encoder.new
6
+
7
+ ### NOTE: All of these settings are optional ###
8
+ # The default setup is 128kbps minimum plus VBR.
9
+
10
+ # Set up the encoder to be 128kbps, NON-VBR
11
+ writer.bitrate = 128
12
+ writer.vbr_type = Encoder::VBR_OFF
13
+
14
+ # Set the ID3 tags
15
+ writer.title = 'tenderlovemaking.com'
16
+ writer.artist = 'Aaron Patterson'
17
+ writer.album = 'ICANHASAUDIO'
18
+ writer.year = 2008
19
+ writer.track = 1
20
+ writer.genre = 'Porn Groove'
21
+
22
+ # Make sure to open your outfile as read and write. Writing VBR tags requires
23
+ # seeking through the file.
24
+ File.open(ARGV[1], 'wb+') { |outfile|
25
+ File.open(ARGV[0], 'rb') { |infile|
26
+ writer.encode(infile, outfile)
27
+ }
28
+ }
data/ext/extconf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ ENV["ARCHFLAGS"] = "-arch #{`uname -p` =~ /powerpc/ ? 'ppc' : 'i386'}"
2
+
1
3
  require 'mkmf'
2
4
 
3
5
  def exit_failure(msg)
data/ext/get_audio.c CHANGED
@@ -10,6 +10,10 @@ get_audio_common(VALUE self, VALUE musicin,
10
10
  int buffer[2][1152], short buffer16[2][1152],
11
11
  mp3data_struct * mp3data);
12
12
 
13
+ int get_audio_pcm(VALUE self, VALUE musicin, int buffer[2][1152]) {
14
+ return 0;
15
+ }
16
+
13
17
  static int
14
18
  read_samples_mp3(VALUE self, VALUE musicin,
15
19
  short int mpg123pcm[2][1152], int stereo, mp3data_struct * mp3data);
data/ext/get_audio.h CHANGED
@@ -1,4 +1,11 @@
1
+ #ifndef GET_AUDIO_H
2
+ #define GET_AUDIO_H
3
+
1
4
  #define MAX_U_32_NUM 0xFFFFFFFF
2
5
  int
3
6
  get_audio16(VALUE self, VALUE musicin, short buffer[2][1152],
4
7
  mp3data_struct * mp3data);
8
+
9
+ int get_audio_pcm(VALUE self, VALUE musicin, int buffer[2][1152]);
10
+
11
+ #endif
data/ext/icanhasaudio.c CHANGED
@@ -6,11 +6,10 @@
6
6
  *
7
7
  * Released under the GPL
8
8
  */
9
- #include <ruby.h>
10
- #include <lame/lame.h>
11
- #include <dlfcn.h>
9
+ #include "icanhasaudio.h"
12
10
  #include "syncword.h"
13
11
  #include "decoder.h"
12
+ #include "mpeg_encoder.h"
14
13
  #include "get_audio.h"
15
14
 
16
15
  static VALUE rb_mAudio;
@@ -164,8 +163,8 @@ void Init_icanhasaudio() {
164
163
  rb_mOgg = rb_define_module_under(rb_mAudio, "OGG");
165
164
  rb_cOggDecoder = rb_define_class_under(rb_mOgg, "Decoder", rb_cObject);
166
165
 
167
- /* VERSION = '0.0.3' */
168
- rb_define_const(rb_cDecoder, "VERSION", rb_str_new2("0.0.3"));
166
+ /* VERSION = '0.1.0' */
167
+ rb_define_const(rb_cDecoder, "VERSION", rb_str_new2("0.1.0"));
169
168
  rb_define_singleton_method(
170
169
  rb_cDecoder,
171
170
  "lame_version",
@@ -176,6 +175,8 @@ void Init_icanhasaudio() {
176
175
  rb_define_alloc_func(rb_cDecoder, reader_allocate);
177
176
  rb_define_method(rb_cDecoder, "decode", method_lame_decode, 2);
178
177
  rb_define_method(rb_cOggDecoder, "decode", method_ogg_decode, 2);
178
+
179
+ init_MpegEncoder(rb_mMpeg);
179
180
  rb_require("icanhasaudio/mpeg");
180
181
  rb_require("icanhasaudio/ogg");
181
182
  }
@@ -0,0 +1,8 @@
1
+ #ifndef ICANHASAUDIO_H
2
+ #define ICANHASAUDIO_H
3
+
4
+ #include <ruby.h>
5
+ #include <lame/lame.h>
6
+ #include <dlfcn.h>
7
+
8
+ #endif
@@ -0,0 +1,528 @@
1
+ #include "mpeg_encoder.h"
2
+ #include <rubyio.h>
3
+
4
+ static VALUE cMpegEncoder;
5
+
6
+ static void encoder_free(lame_global_flags * gfp) {
7
+ lame_close(gfp);
8
+ }
9
+
10
+ /*
11
+ * call-seq:
12
+ * Audio::MPEG::Encoder.new
13
+ *
14
+ * Returns a new MPEG Encoder object.
15
+ */
16
+ static VALUE
17
+ encoder_allocate(VALUE klass) {
18
+ lame_global_flags * gfp = lame_init();
19
+ id3tag_init(gfp);
20
+
21
+ return Data_Wrap_Struct(klass, NULL, encoder_free, gfp);
22
+ }
23
+
24
+ /* Public methods. */
25
+
26
+ /*
27
+ * call-seq:
28
+ * encoder.vbr_hard_min=
29
+ *
30
+ * Strictly enforce the vbr min bitrate. Normally it will be violated for
31
+ * analog silence.
32
+ */
33
+ static VALUE MpegEncoder_set_vbr_hard_min(VALUE self, VALUE boolean) {
34
+ lame_global_flags * gfp;
35
+
36
+ Data_Get_Struct(self, lame_global_flags, gfp);
37
+ lame_set_VBR_hard_min(gfp, boolean == Qtrue ? 1 : 0);
38
+ return boolean;
39
+ }
40
+
41
+ /*
42
+ * call-seq:
43
+ * encoder.vbr_hard_min?
44
+ *
45
+ * Get the hard minimum flag.
46
+ */
47
+ static VALUE MpegEncoder_get_vbr_hard_min(VALUE self) {
48
+ lame_global_flags * gfp;
49
+
50
+ Data_Get_Struct(self, lame_global_flags, gfp);
51
+ return lame_get_VBR_hard_min(gfp) == 0 ? Qfalse : Qtrue;
52
+ }
53
+
54
+ /*
55
+ * call-seq:
56
+ * encoder.vbr_max_bitrate=
57
+ *
58
+ * Set the maximum vbr bitrate.
59
+ */
60
+ static VALUE MpegEncoder_set_vbr_max_bitrate(VALUE self, VALUE brate) {
61
+ lame_global_flags * gfp;
62
+
63
+ Data_Get_Struct(self, lame_global_flags, gfp);
64
+ lame_set_VBR_max_bitrate_kbps(gfp, NUM2INT(brate));
65
+ return brate;
66
+ }
67
+
68
+ /*
69
+ * call-seq:
70
+ * encoder.vbr_max_bitrate
71
+ *
72
+ * Get the maximum vbr bitrate.
73
+ */
74
+ static VALUE MpegEncoder_get_vbr_max_bitrate(VALUE self) {
75
+ lame_global_flags * gfp;
76
+
77
+ Data_Get_Struct(self, lame_global_flags, gfp);
78
+ return INT2NUM(lame_get_VBR_max_bitrate_kbps(gfp));
79
+ }
80
+
81
+ /*
82
+ * call-seq:
83
+ * encoder.vbr_min_bitrate=
84
+ *
85
+ * Set the minimum vbr bitrate.
86
+ */
87
+ static VALUE MpegEncoder_set_vbr_min_bitrate(VALUE self, VALUE brate) {
88
+ lame_global_flags * gfp;
89
+
90
+ Data_Get_Struct(self, lame_global_flags, gfp);
91
+ lame_set_VBR_min_bitrate_kbps(gfp, NUM2INT(brate));
92
+ return brate;
93
+ }
94
+
95
+ /*
96
+ * call-seq:
97
+ * encoder.vbr_min_bitrate
98
+ *
99
+ * Get the minimum vbr bitrate.
100
+ */
101
+ static VALUE MpegEncoder_get_vbr_min_bitrate(VALUE self) {
102
+ lame_global_flags * gfp;
103
+
104
+ Data_Get_Struct(self, lame_global_flags, gfp);
105
+ return INT2NUM(lame_get_VBR_min_bitrate_kbps(gfp));
106
+ }
107
+
108
+ /*
109
+ * call-seq:
110
+ * encoder.bitrate=
111
+ *
112
+ * Set the bitrate.
113
+ */
114
+ static VALUE MpegEncoder_set_bitrate(VALUE self, VALUE brate) {
115
+ lame_global_flags * gfp;
116
+
117
+ Data_Get_Struct(self, lame_global_flags, gfp);
118
+ lame_set_brate(gfp, NUM2INT(brate));
119
+ lame_set_VBR_min_bitrate_kbps(gfp, lame_get_brate(gfp));
120
+ return brate;
121
+ }
122
+
123
+ /*
124
+ * call-seq:
125
+ * encoder.bitrate
126
+ *
127
+ * Get the bitrate.
128
+ */
129
+ static VALUE MpegEncoder_get_bitrate(VALUE self) {
130
+ lame_global_flags * gfp;
131
+
132
+ Data_Get_Struct(self, lame_global_flags, gfp);
133
+ return INT2NUM(lame_get_brate(gfp));
134
+ }
135
+
136
+ /*
137
+ * call-seq:
138
+ * encoder.quality=
139
+ *
140
+ * Set the VBR quality. 0 = highest, 9 = lowest
141
+ */
142
+ static VALUE MpegEncoder_set_vbr_quality(VALUE self, VALUE quality) {
143
+ lame_global_flags * gfp;
144
+
145
+ Data_Get_Struct(self, lame_global_flags, gfp);
146
+ lame_set_VBR_q(gfp, NUM2INT(quality));
147
+ return quality;
148
+ }
149
+
150
+ /*
151
+ * call-seq:
152
+ * encoder.quality
153
+ *
154
+ * Get the VBR quality. 0 = highest, 9 = lowest
155
+ */
156
+ static VALUE MpegEncoder_get_vbr_quality(VALUE self) {
157
+ lame_global_flags * gfp;
158
+
159
+ Data_Get_Struct(self, lame_global_flags, gfp);
160
+ return INT2NUM(lame_get_VBR_q(gfp));
161
+ }
162
+
163
+ /*
164
+ * call-seq:
165
+ * encoder.vbr_type=
166
+ *
167
+ * Set the type of VBR. Must be VBR_OFF, VBR_NORMAL, or VBR_FAST
168
+ */
169
+ static VALUE MpegEncoder_set_vbr_type(VALUE self, VALUE type) {
170
+ lame_global_flags * gfp;
171
+
172
+ Data_Get_Struct(self, lame_global_flags, gfp);
173
+ lame_set_VBR(gfp, NUM2INT(type));
174
+ return type;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * encoder.vbr_type
180
+ *
181
+ * Get the type of VBR.
182
+ */
183
+ static VALUE MpegEncoder_get_vbr_type(VALUE self) {
184
+ lame_global_flags * gfp;
185
+
186
+ Data_Get_Struct(self, lame_global_flags, gfp);
187
+ return INT2NUM(lame_get_VBR(gfp));
188
+ }
189
+
190
+ /*
191
+ * call-seq:
192
+ * encoder.print_config
193
+ *
194
+ * Print the encoder configuration.
195
+ */
196
+ static VALUE MpegEncoder_print_config(VALUE self) {
197
+ lame_global_flags * gfp;
198
+
199
+ Data_Get_Struct(self, lame_global_flags, gfp);
200
+ lame_print_config(gfp);
201
+ return Qnil;
202
+ }
203
+
204
+ /*
205
+ * call-seq:
206
+ * encoder.artist=
207
+ *
208
+ * Set the ID3 artist.
209
+ */
210
+ static VALUE MpegEncoder_set_artist(VALUE self, VALUE artist) {
211
+ lame_global_flags * gfp;
212
+
213
+ Data_Get_Struct(self, lame_global_flags, gfp);
214
+ id3tag_set_artist(gfp, StringValuePtr(artist));
215
+ return artist;
216
+ }
217
+
218
+ /*
219
+ * call-seq:
220
+ * encoder.title=
221
+ *
222
+ * Set the ID3 title.
223
+ */
224
+ static VALUE MpegEncoder_set_title(VALUE self, VALUE title) {
225
+ lame_global_flags * gfp;
226
+
227
+ Data_Get_Struct(self, lame_global_flags, gfp);
228
+ id3tag_set_title(gfp, StringValuePtr(title));
229
+ return title;
230
+ }
231
+
232
+ /*
233
+ * call-seq:
234
+ * encoder.album=
235
+ *
236
+ * Set the ID3 album.
237
+ */
238
+ static VALUE MpegEncoder_set_album(VALUE self, VALUE album) {
239
+ lame_global_flags * gfp;
240
+
241
+ Data_Get_Struct(self, lame_global_flags, gfp);
242
+ id3tag_set_album(gfp, StringValuePtr(album));
243
+ return album;
244
+ }
245
+
246
+ /*
247
+ * call-seq:
248
+ * encoder.year=
249
+ *
250
+ * Set the ID3 year.
251
+ */
252
+ static VALUE MpegEncoder_set_year(VALUE self, VALUE year) {
253
+ lame_global_flags * gfp;
254
+ VALUE * year_string;
255
+
256
+ Data_Get_Struct(self, lame_global_flags, gfp);
257
+ year_string = rb_funcall(year, rb_intern("to_s"), 0);
258
+ id3tag_set_year(gfp, StringValuePtr(year_string));
259
+ return year;
260
+ }
261
+
262
+ /*
263
+ * call-seq:
264
+ * encoder.track=
265
+ *
266
+ * Set the ID3 track.
267
+ */
268
+ static VALUE MpegEncoder_set_track(VALUE self, VALUE track) {
269
+ lame_global_flags * gfp;
270
+ int track_number;
271
+ VALUE * track_string;
272
+
273
+ track_number = NUM2INT(track);
274
+ if(track < 0 || track > 255)
275
+ rb_raise(rb_eRuntimeError, "Track must be between 0 and 255.\n");
276
+
277
+ Data_Get_Struct(self, lame_global_flags, gfp);
278
+ track_string = rb_funcall(track, rb_intern("to_s"), 0);
279
+ id3tag_set_track(gfp, StringValuePtr(track_string));
280
+ return track;
281
+ }
282
+
283
+ /*
284
+ * call-seq:
285
+ * encoder.genre=
286
+ *
287
+ * Set the ID3 genre.
288
+ */
289
+ static VALUE MpegEncoder_set_genre(VALUE self, VALUE genre) {
290
+ lame_global_flags * gfp;
291
+
292
+ Data_Get_Struct(self, lame_global_flags, gfp);
293
+ id3tag_set_genre(gfp, StringValuePtr(genre));
294
+ return genre;
295
+ }
296
+
297
+ /* Private methods. */
298
+
299
+ static VALUE MpegEncoder_write_vbr_tag(VALUE self) {
300
+ lame_global_flags * gfp;
301
+
302
+ Data_Get_Struct(self, lame_global_flags, gfp);
303
+ if(lame_get_bWriteVbrTag(gfp))
304
+ return Qtrue;
305
+ return Qfalse;
306
+ }
307
+
308
+ static VALUE MpegEncoder_print_internals(VALUE self) {
309
+ lame_global_flags * gfp;
310
+
311
+ Data_Get_Struct(self, lame_global_flags, gfp);
312
+ lame_print_internals(gfp);
313
+ return Qnil;
314
+ }
315
+
316
+ static VALUE MpegEncoder_get_mpeg_quality(VALUE self) {
317
+ lame_global_flags * gfp;
318
+
319
+ Data_Get_Struct(self, lame_global_flags, gfp);
320
+ return INT2NUM(lame_get_quality(gfp));
321
+ }
322
+
323
+ static VALUE MpegEncoder_get_compression_ratio(VALUE self) {
324
+ lame_global_flags * gfp;
325
+
326
+ Data_Get_Struct(self, lame_global_flags, gfp);
327
+ return rb_float_new(lame_get_compression_ratio(gfp));
328
+ }
329
+
330
+ static VALUE MpegEncoder_get_mpeg_version(VALUE self) {
331
+ lame_global_flags * gfp;
332
+
333
+ Data_Get_Struct(self, lame_global_flags, gfp);
334
+ return INT2NUM(lame_get_version(gfp));
335
+ }
336
+
337
+ static VALUE MpegEncoder_get_mpeg_mode(VALUE self) {
338
+ lame_global_flags * gfp;
339
+
340
+ Data_Get_Struct(self, lame_global_flags, gfp);
341
+ return INT2NUM(lame_get_mode(gfp));
342
+ }
343
+
344
+ static VALUE MpegEncoder_get_force_ms(VALUE self) {
345
+ lame_global_flags * gfp;
346
+
347
+ Data_Get_Struct(self, lame_global_flags, gfp);
348
+ return INT2NUM(lame_get_force_ms(gfp));
349
+ }
350
+
351
+ static VALUE MpegEncoder_get_out_samplerate(VALUE self) {
352
+ lame_global_flags * gfp;
353
+
354
+ Data_Get_Struct(self, lame_global_flags, gfp);
355
+ return INT2NUM(lame_get_out_samplerate(gfp));
356
+ }
357
+
358
+ static VALUE MpegEncoder_set_in_samplerate(VALUE self, VALUE samplerate) {
359
+ lame_global_flags * gfp;
360
+
361
+ Data_Get_Struct(self, lame_global_flags, gfp);
362
+ lame_set_in_samplerate(gfp, NUM2INT(samplerate));
363
+ return samplerate;
364
+ }
365
+
366
+ static VALUE MpegEncoder_set_num_samples(VALUE self, VALUE num_samples) {
367
+ lame_global_flags * gfp;
368
+
369
+ Data_Get_Struct(self, lame_global_flags, gfp);
370
+ lame_set_num_samples(gfp, NUM2ULONG(num_samples));
371
+ return num_samples;
372
+ }
373
+
374
+ static VALUE MpegEncoder_get_num_samples(VALUE self) {
375
+ lame_global_flags * gfp;
376
+
377
+ Data_Get_Struct(self, lame_global_flags, gfp);
378
+ return ULONG2NUM(lame_get_num_samples(gfp));
379
+ }
380
+
381
+ static VALUE MpegEncoder_set_num_channels(VALUE self, VALUE num_channels) {
382
+ lame_global_flags * gfp;
383
+
384
+ Data_Get_Struct(self, lame_global_flags, gfp);
385
+ lame_set_num_channels(gfp, NUM2INT(num_channels));
386
+ return num_channels;
387
+ }
388
+
389
+ static VALUE MpegEncoder_get_num_channels(VALUE self) {
390
+ lame_global_flags * gfp;
391
+
392
+ Data_Get_Struct(self, lame_global_flags, gfp);
393
+ return INT2NUM(lame_get_num_channels(gfp));
394
+ }
395
+
396
+ static VALUE MpegEncoder_get_framesize(VALUE self) {
397
+ lame_global_flags * gfp;
398
+
399
+ Data_Get_Struct(self, lame_global_flags, gfp);
400
+ return INT2NUM(lame_get_framesize(gfp));
401
+ }
402
+
403
+ static VALUE MpegEncoder_encoder_buffer(VALUE self, VALUE left, VALUE right) {
404
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
405
+ int * buffer_left;
406
+ int * buffer_right;
407
+ int length, i;
408
+ int imp3;
409
+ lame_global_flags * gfp;
410
+
411
+ Data_Get_Struct(self, lame_global_flags, gfp);
412
+
413
+ length = NUM2INT(rb_funcall(left, rb_intern("length"), 0));
414
+ buffer_left = calloc(length, sizeof(int));
415
+ buffer_right = calloc(length, sizeof(int));
416
+
417
+ for(i = 0; i < length; i++) {
418
+ buffer_left[i] = NUM2UINT(rb_funcall(left, rb_intern("[]"), 1, INT2NUM(i)));
419
+ buffer_right[i] = NUM2UINT(rb_funcall(right, rb_intern("[]"), 1,INT2NUM(i)));
420
+ }
421
+
422
+ imp3 = lame_encode_buffer_int(gfp, buffer_left, buffer_right, length,
423
+ mp3buffer, sizeof(mp3buffer));
424
+
425
+ free(buffer_left);
426
+ free(buffer_right);
427
+
428
+ if(imp3 < 0) {
429
+ if(imp3 == -1)
430
+ rb_raise(rb_eRuntimeError, "Mp3 buffer is not big enough.\n");
431
+ else
432
+ rb_raise(rb_eRuntimeError, "internal error.\n");
433
+ }
434
+ return rb_str_new(mp3buffer, imp3);
435
+ }
436
+
437
+ static VALUE MpegEncoder_flush(VALUE self) {
438
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
439
+ int imp3;
440
+ lame_global_flags * gfp;
441
+
442
+ Data_Get_Struct(self, lame_global_flags, gfp);
443
+ imp3 = lame_encode_flush(gfp, mp3buffer, sizeof(mp3buffer));
444
+ if(imp3 < 0) {
445
+ if(imp3 == -1)
446
+ rb_raise(rb_eRuntimeError, "Mp3 buffer is not big enough.\n");
447
+ else
448
+ rb_raise(rb_eRuntimeError, "internal error.\n");
449
+ }
450
+ return rb_str_new(mp3buffer, imp3);
451
+ }
452
+
453
+ static VALUE MpegEncoder_write_vbr_tags(VALUE self, VALUE outfile) {
454
+ OpenFile *fp;
455
+ lame_global_flags * gfp;
456
+
457
+ GetOpenFile(outfile, fp);
458
+
459
+ Data_Get_Struct(self, lame_global_flags, gfp);
460
+ lame_mp3_tags_fid(gfp, fp->f);
461
+ return Qnil;
462
+ }
463
+
464
+ static VALUE MpegEncoder_init_params(VALUE self) {
465
+ lame_global_flags * gfp;
466
+
467
+ Data_Get_Struct(self, lame_global_flags, gfp);
468
+
469
+ if(lame_init_params(gfp) < 0) {
470
+ rb_raise(rb_eRuntimeError, "Fatal error during initialization.\n");
471
+ }
472
+
473
+ return Qnil;
474
+ }
475
+
476
+ void init_MpegEncoder(VALUE rb_mMpeg) {
477
+ /*
478
+ rb_mAudio = rb_define_module("Audio");
479
+ rb_mMpeg = rb_define_module_under(rb_mAudio, "MPEG");
480
+ */
481
+ /*
482
+ * Encode mp3s
483
+ */
484
+ cMpegEncoder = rb_define_class_under(rb_mMpeg, "Encoder", rb_cObject);
485
+ rb_define_alloc_func(cMpegEncoder, encoder_allocate);
486
+
487
+ /* Public Methods */
488
+
489
+ rb_define_method(cMpegEncoder, "vbr_quality=",MpegEncoder_set_vbr_quality, 1);
490
+ rb_define_method(cMpegEncoder, "vbr_quality", MpegEncoder_get_vbr_quality, 0);
491
+ rb_define_method(cMpegEncoder, "vbr_type=", MpegEncoder_set_vbr_type, 1);
492
+ rb_define_method(cMpegEncoder, "vbr_type", MpegEncoder_get_vbr_type, 0);
493
+ rb_define_method(cMpegEncoder, "print_config", MpegEncoder_print_config, 0);
494
+ rb_define_method(cMpegEncoder, "title=", MpegEncoder_set_title, 1);
495
+ rb_define_method(cMpegEncoder, "artist=", MpegEncoder_set_artist, 1);
496
+ rb_define_method(cMpegEncoder, "album=", MpegEncoder_set_album, 1);
497
+ rb_define_method(cMpegEncoder, "year=", MpegEncoder_set_year, 1);
498
+ rb_define_method(cMpegEncoder, "track=", MpegEncoder_set_track, 1);
499
+ rb_define_method(cMpegEncoder, "genre=", MpegEncoder_set_genre, 1);
500
+ rb_define_method(cMpegEncoder, "bitrate=", MpegEncoder_set_bitrate, 1);
501
+ rb_define_method(cMpegEncoder, "bitrate", MpegEncoder_get_bitrate, 0);
502
+ rb_define_method(cMpegEncoder, "vbr_min_bitrate=", MpegEncoder_set_vbr_min_bitrate, 1);
503
+ rb_define_method(cMpegEncoder, "vbr_min_bitrate", MpegEncoder_get_vbr_min_bitrate, 0);
504
+ rb_define_method(cMpegEncoder, "vbr_max_bitrate=", MpegEncoder_set_vbr_max_bitrate, 1);
505
+ rb_define_method(cMpegEncoder, "vbr_max_bitrate", MpegEncoder_get_vbr_max_bitrate, 0);
506
+ rb_define_method(cMpegEncoder, "vbr_hard_min=", MpegEncoder_set_vbr_hard_min, 1);
507
+ rb_define_method(cMpegEncoder, "vbr_hard_min?", MpegEncoder_get_vbr_hard_min, 0);
508
+
509
+
510
+ rb_define_private_method(cMpegEncoder, "init_params", MpegEncoder_init_params, 0);
511
+ rb_define_private_method(cMpegEncoder, "num_channels=", MpegEncoder_set_num_channels, 1);
512
+ rb_define_private_method(cMpegEncoder, "num_channels", MpegEncoder_get_num_channels, 0);
513
+ rb_define_private_method(cMpegEncoder, "in_samplerate=", MpegEncoder_set_in_samplerate, 1);
514
+ rb_define_private_method(cMpegEncoder, "num_samples=", MpegEncoder_set_num_samples, 1);
515
+ rb_define_private_method(cMpegEncoder, "num_samples", MpegEncoder_get_num_samples, 0);
516
+ rb_define_private_method(cMpegEncoder, "out_samplerate", MpegEncoder_get_out_samplerate, 0);
517
+ rb_define_private_method(cMpegEncoder, "framesize", MpegEncoder_get_framesize, 0);
518
+ rb_define_private_method(cMpegEncoder, "encode_buffer", MpegEncoder_encoder_buffer, 2);
519
+ rb_define_private_method(cMpegEncoder, "flush", MpegEncoder_flush, 0);
520
+ rb_define_private_method(cMpegEncoder, "write_vbr_tags", MpegEncoder_write_vbr_tags, 1);
521
+ rb_define_private_method(cMpegEncoder, "force_ms", MpegEncoder_get_force_ms, 0);
522
+ rb_define_private_method(cMpegEncoder, "mpeg_mode", MpegEncoder_get_mpeg_mode, 0);
523
+ rb_define_private_method(cMpegEncoder, "mpeg_version", MpegEncoder_get_mpeg_version, 0);
524
+ rb_define_private_method(cMpegEncoder, "compression_ratio", MpegEncoder_get_compression_ratio, 0);
525
+ rb_define_private_method(cMpegEncoder, "mpeg_quality", MpegEncoder_get_mpeg_quality, 0);
526
+ rb_define_private_method(cMpegEncoder, "print_internals", MpegEncoder_print_internals, 0);
527
+ rb_define_private_method(cMpegEncoder, "write_vbr_tag?", MpegEncoder_write_vbr_tag, 0);
528
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef MPEG_ENCODER_H
2
+ #define MPEG_ENCODER_H
3
+
4
+ #include "icanhasaudio.h"
5
+ #include "get_audio.h"
6
+
7
+ #define LAME_MAXMP3BUFFER 16384
8
+ void init_MpegEncoder(VALUE mMpeg);
9
+
10
+ #endif
@@ -1,3 +1,5 @@
1
+ require 'icanhasaudio/mpeg/encoder'
2
+
1
3
  class Audio::MPEG::Decoder
2
4
  attr_reader :stereo, :samplerate, :bitrate, :mode, :mode_ext, :framesize
3
5
 
@@ -0,0 +1,241 @@
1
+ module Audio
2
+ module MPEG
3
+ class Encoder
4
+ WAV_ID_RIFF = 0x52494646
5
+ WAV_ID_WAVE = 0x57415645 # "WAVE"
6
+ WAV_ID_FMT = 0x666d7420 # "fmt "
7
+ WAV_ID_DATA = 0x64617461 # "data"
8
+
9
+ IFF_ID_FORM = 0x464f524d # "FORM"
10
+ IFF_ID_AIFF = 0x41494646 # "AIFF"
11
+ IFF_ID_AIFC = 0x41494643 # "AIFC"
12
+ IFF_ID_COMM = 0x434f4d4d # "COMM"
13
+ IFF_ID_SSND = 0x53534e44 # "SSND"
14
+
15
+ IFF_ID_NONE = 0x4e4f4e45 # "NONE" AIFF-C data format
16
+ IFF_ID_2CBE = 0x74776f73 # "twos" AIFF-C data format
17
+ IFF_ID_2CLE = 0x736f7774 # "sowt" AIFF-C data format
18
+
19
+
20
+ VBR_OFF = 0
21
+ VBR_NORMAL = 2
22
+ VBR_FAST = 4
23
+
24
+ MODE_NAMES = [
25
+ [ 'stereo', 'j-stereo', 'dual-ch', 'single-ch' ],
26
+ [ 'stereo', 'force-ms', 'dual-ch', 'single-ch' ],
27
+ ]
28
+
29
+ attr_accessor :pcmbitwidth
30
+ attr_accessor :logger
31
+ def initialize
32
+ @pcmbitwidth = 16
33
+ @logger = nil
34
+ self.vbr_quality = 2
35
+ self.vbr_type = VBR_NORMAL
36
+ end
37
+
38
+ def encode(infile, outfile)
39
+ raise "Out file must be a FILE. :-(" unless outfile.is_a?(File)
40
+
41
+ num_samples = 0xFFFFFFFF
42
+ parse_header(infile)
43
+ init_params
44
+
45
+ logger.debug(encoding_info) if logger
46
+
47
+ num_samples_read = 0
48
+
49
+ sw = case @pcmbitwidth
50
+ when 8
51
+ 32 - 8
52
+ when 16
53
+ 32 - 16
54
+ when 24
55
+ 32 - 24
56
+ end
57
+ while !infile.eof?
58
+ tmp_num_samples = num_samples()
59
+ samples_to_read = framesize()
60
+ remaining = tmp_num_samples - [tmp_num_samples, num_samples_read].min
61
+ if remaining < framesize && 0 != tmp_num_samples
62
+ samples_to_read = remaining
63
+ end
64
+
65
+ read_size = num_channels * samples_to_read * (pcmbitwidth / 8)
66
+
67
+ samples = infile.read(read_size)
68
+ samples_read = samples.length / num_channels
69
+
70
+ buffers = [[], []]
71
+ samples.unpack('v*').each_with_index do |b,i|
72
+ (buffers[(i % 2)]) << (b << sw)
73
+ end
74
+ outfile.write(encode_buffer(buffers[0], buffers[1]))
75
+ end
76
+ outfile.write(flush())
77
+ write_vbr_tags(outfile) if write_vbr_tag?
78
+ end
79
+
80
+ private
81
+ def encoding_info
82
+ sprintf("Encoding as %g kHz ", 1e-3 * out_samplerate) +
83
+ sprintf("VBR(q=%i)", vbr_quality) +
84
+ sprintf(" %s MPEG-%u%s Layer III (%s%gx) qval=%i\n",
85
+ MODE_NAMES[force_ms][mpeg_mode],
86
+ 2 - mpeg_version,
87
+ out_samplerate < 16000 ? ".5" : '',
88
+ '',
89
+ 0.1 * (10.0 * compression_ratio + 0.5).to_i,
90
+ mpeg_quality)
91
+ end
92
+
93
+ def parse_header(file)
94
+ header = file.read(4).unpack('N').first
95
+ case header
96
+ when WAV_ID_RIFF # Wave file
97
+ parse_wave_header(file)
98
+ when IFF_ID_FORM # AIFF file
99
+ parse_aiff_header(file)
100
+ else
101
+ $stderr.puts "Assuming RAW PCM"
102
+ file.rewind
103
+ end
104
+ end
105
+
106
+ def parse_aiff_header(file)
107
+ chunk_size = file.read(4).unpack('N').first
108
+ type_id = file.read(4).unpack('N').first
109
+
110
+ raise unless [IFF_ID_AIFF, IFF_ID_AIFC].any? { |x| type_id == x }
111
+
112
+ sub_size = 0
113
+ sample_type = nil
114
+ sample_size = nil
115
+ num_channels = nil
116
+ block_size = nil
117
+ sample_rate = nil
118
+ is_aiff = false
119
+ while chunk_size > 0
120
+ type = file.read(4).unpack('N').first
121
+ chunk_size -= 4
122
+
123
+ case type
124
+ when IFF_ID_COMM
125
+ sub_size = file.read(4).unpack('N').first
126
+ chunk_size -= 4
127
+
128
+ num_channels = file.read(2).unpack('n').first
129
+ sub_size -= 2
130
+ num_sample_frames = file.read(4).unpack('N').first
131
+ sub_size -= 4
132
+ sample_size = file.read(2).unpack('n').first
133
+ sub_size -= 2
134
+ sample_rate = unpack_ieee(file.read(10))
135
+ sub_size -= 10
136
+
137
+ if type_id == IFF_ID_AIFC
138
+ data_type = file.read(4).unpack('N').first
139
+ sub_size -=4
140
+
141
+ raise unless [ IFF_ID_2CLE,
142
+ IFF_ID_2CBE,
143
+ IFF_ID_NONE,
144
+ ].any? { |x| data_type == x }
145
+
146
+ #if sample_size == 16
147
+ # swap bytes....
148
+ end
149
+
150
+ file.read(sub_size)
151
+ when IFF_ID_SSND
152
+ sub_size = file.read(4).unpack('N').first
153
+ chunk_size -= sub_size
154
+
155
+ block_offset = file.read(4).unpack('N').first
156
+ sub_size -= 4
157
+ block_size = file.read(4).unpack('N').first
158
+ sub_size -= 4
159
+
160
+ sample_type = IFF_ID_SSND
161
+ file.read(block_offset)
162
+ is_aiff = true
163
+ break
164
+ else
165
+ sub_size = file.read(4).unpack('N').first
166
+ chunk_size -= sub_size
167
+ file.read(sub_size)
168
+ end
169
+ end
170
+
171
+ # Validate the header
172
+ if is_aiff
173
+ raise "Sound data is not PCM" unless sample_type == IFF_ID_SSND
174
+ raise "Sound data is not 16 bits" unless sample_size == 16
175
+ unless num_channels == 1 || num_channels == 2
176
+ raise "Sound data is not mono or stereo"
177
+ end
178
+ raise "Block size is not 0 bytes" unless block_size == 0
179
+ end
180
+
181
+ @pcmbitwidth = sample_size
182
+ self.num_channels = num_channels
183
+ self.in_samplerate = sample_rate.to_i
184
+ self.num_samples = num_sample_frames
185
+ end
186
+
187
+ def unpack_ieee(data)
188
+ (expon, hi_mant, lo_mant) = data.unpack('nNN')
189
+ expon -= 16383
190
+ hi_mant * (2 ** (expon -= 31)) + lo_mant * (2 ** (expon -= 32))
191
+ end
192
+
193
+ def parse_wave_header(file)
194
+ format_tag = nil
195
+ channels = nil
196
+ samples_per_sec = nil
197
+ avg_bytes_per_sec = nil
198
+ block_align = nil
199
+ bits_per_sample = nil
200
+ is_wav = false
201
+ data_length = 0
202
+
203
+ file_length = file.read(4).unpack('N').first
204
+ raise "Corrupt wave" if file.read(4).unpack('N').first != WAV_ID_WAVE
205
+ 20.times {
206
+ type = file.read(4).unpack('N').first
207
+ case type
208
+ when WAV_ID_FMT
209
+ sub_size = file.read(4).unpack('V').first
210
+ raise "Corrupt wave" if sub_size < 16
211
+
212
+ ( format_tag,
213
+ channels,
214
+ samples_per_sec,
215
+ avg_bytes_per_sec,
216
+ block_align, bits_per_sample) = *(file.read(16).unpack('vvVVvv'))
217
+ sub_size -= 16
218
+
219
+ file.read(sub_size) if sub_size > 0
220
+ when WAV_ID_DATA
221
+ sub_size = file.read(4).unpack('V').first
222
+ data_length = sub_size
223
+ is_wav = true
224
+ break;
225
+ else
226
+ sub_size = file.read(4).unpack('V').first
227
+ file.read(sub_size)
228
+ end
229
+ }
230
+ raise "Unsupported format" unless format_tag == 1
231
+ raise unless is_wav
232
+
233
+ self.num_channels = channels
234
+ self.in_samplerate = samples_per_sec
235
+ self.num_samples = data_length / (channels * ((bits_per_sample+7)/8))
236
+ @pcmbitwidth = bits_per_sample
237
+ is_wav
238
+ end
239
+ end
240
+ end
241
+ end
Binary file
@@ -0,0 +1,120 @@
1
+ require 'test/unit'
2
+ require 'icanhasaudio'
3
+ require 'tempfile'
4
+
5
+ class MPEGEncoderTest < Test::Unit::TestCase
6
+ include Audio::MPEG
7
+
8
+ WAV_FILE = File.dirname(__FILE__) + "/assets/testcase.wav"
9
+ #AIFF_FILE = File.dirname(__FILE__) + "/assets/cow.aiff"
10
+
11
+ def setup
12
+ @encoder = Audio::MPEG::Encoder.new
13
+ assert File.exists?(WAV_FILE)
14
+ #assert File.exists?(AIFF_FILE)
15
+ end
16
+
17
+ def test_encoder_initialize
18
+ assert Audio::MPEG::Encoder.new
19
+ end
20
+
21
+ def test_encode
22
+ File.open("#{Dir::tmpdir}/out.mp3", 'wb+') { |outfile|
23
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
24
+ }
25
+ end
26
+
27
+ def test_set_bitrate
28
+ @encoder.bitrate = 128
29
+ assert_equal(128, @encoder.bitrate)
30
+ assert_equal(128, @encoder.vbr_min_bitrate)
31
+ end
32
+
33
+ def test_vbr_type
34
+ @encoder.vbr_type = Encoder::VBR_OFF
35
+ assert_equal(Encoder::VBR_OFF, @encoder.vbr_type)
36
+ File.open("#{Dir::tmpdir}/no_vbr.mp3", 'wb+') { |outfile|
37
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
38
+ }
39
+ end
40
+
41
+ def test_set_min_vbr_bitrate
42
+ @encoder.vbr_min_bitrate = 128
43
+ assert_equal(128, @encoder.vbr_min_bitrate)
44
+ end
45
+
46
+ def test_set_vbr_max_bitrate
47
+ @encoder.vbr_max_bitrate = 128
48
+ assert_equal(128, @encoder.vbr_max_bitrate)
49
+ @encoder.vbr_max_bitrate = 256
50
+ assert_equal(256, @encoder.vbr_max_bitrate)
51
+ end
52
+
53
+ def test_set_vbr_hard_min
54
+ assert_equal(false, @encoder.vbr_hard_min?)
55
+ @encoder.vbr_hard_min = true
56
+ assert_equal(true, @encoder.vbr_hard_min?)
57
+ @encoder.vbr_hard_min = false
58
+ assert_equal(false, @encoder.vbr_hard_min?)
59
+ end
60
+
61
+ def test_set_title
62
+ @encoder.title = 'tenderlovemaking.com'
63
+
64
+ File.open("#{Dir::tmpdir}/title.mp3", 'wb+') { |outfile|
65
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
66
+ }
67
+ end
68
+
69
+ def test_set_artist
70
+ @encoder.artist = 'Aaron Patterson'
71
+
72
+ File.open("#{Dir::tmpdir}/artist.mp3", 'wb+') { |outfile|
73
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
74
+ }
75
+ end
76
+
77
+ def test_set_album
78
+ @encoder.album = 'Some Album'
79
+
80
+ File.open("#{Dir::tmpdir}/album.mp3", 'wb+') { |outfile|
81
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
82
+ }
83
+ end
84
+
85
+ def test_set_year
86
+ @encoder.year = 1999
87
+
88
+ File.open("#{Dir::tmpdir}/year.mp3", 'wb+') { |outfile|
89
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
90
+ }
91
+ end
92
+
93
+ def test_set_track
94
+ @encoder.track = 1
95
+
96
+ File.open("#{Dir::tmpdir}/track.mp3", 'wb+') { |outfile|
97
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
98
+ }
99
+ end
100
+
101
+ def test_set_genre
102
+ @encoder.genre = 'Porn Groove'
103
+
104
+ File.open("#{Dir::tmpdir}/genre.mp3", 'wb+') { |outfile|
105
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
106
+ }
107
+ end
108
+
109
+ def test_set_all
110
+ @encoder.title = 'tenderlovemaking.com'
111
+ @encoder.artist = 'Aaron Patterson'
112
+ @encoder.album = 'ICANHASAUDIO'
113
+ @encoder.year = 2008
114
+ @encoder.track = 1
115
+ @encoder.genre = 'Rock'
116
+ File.open("#{Dir::tmpdir}/all.mp3", 'wb+') { |outfile|
117
+ @encoder.encode(File.open(WAV_FILE, 'rb'), outfile)
118
+ }
119
+ end
120
+ end
metadata CHANGED
@@ -1,81 +1,92 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
3
- specification_version: 1
4
2
  name: icanhasaudio
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.0.3
7
- date: 2007-08-05 00:00:00 -07:00
8
- summary: icanhasaudio is a lame/vorbis wrapper for decoding ur mp3s and ur oggs.
9
- require_paths:
10
- - lib
11
- - ext
12
- email: aaronp@rubyforge.org
13
- homepage: http://seattlerb.rubyforge.org/
14
- rubyforge_project: seattlerb
15
- description: "Hai! icanhasaudio? is an interface to lame for decoding ur MP3s. I iz in ur
16
- computer. Decodin ur mp3s. Whatevs! I also decodin ur OGGz! == SYNOPSYS
17
- ROFLOL require 'icanhasaudio' reader = Audio::MPEG::Decoder.new
18
- File.open(ARGV[0], 'rb') { |input_lol| File.open(ARGV[1], 'wb') { |output_lol|
19
- reader.decode(input_lol, output_lol) } }"
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Patterson
20
8
  autorequire:
21
- default_executable:
22
9
  bindir: bin
23
- has_rdoc: true
24
- required_ruby_version: !ruby/object:Gem::Version::Requirement
25
- requirements:
26
- -
27
- - ">"
10
+ cert_chain: []
11
+
12
+ date: 2008-02-15 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
28
21
  - !ruby/object:Gem::Version
29
- version: 0.0.0
30
- version:
31
- platform: ruby
32
- signing_key:
33
- cert_chain:
34
- post_install_message:
35
- authors:
36
- - Aaron Patterson
37
- files:
38
- - History.txt
39
- - LICENSE.txt
40
- - Manifest.txt
41
- - README.txt
42
- - Rakefile
43
- - examples/decoder.rb
44
- - examples/kexp.rb
45
- - ext/decoder.c
46
- - ext/decoder.h
47
- - ext/extconf.rb
48
- - ext/get_audio.c
49
- - ext/get_audio.h
50
- - ext/icanhasaudio.c
51
- - ext/rb_ogg.c
52
- - ext/rb_wav.c
53
- - ext/rb_wav.h
54
- - ext/syncword.c
55
- - ext/syncword.h
56
- - lib/icanhasaudio/mpeg.rb
57
- - lib/icanhasaudio/ogg.rb
58
- test_files: []
59
- rdoc_options:
60
- - "--main"
61
- - README.txt
62
- extra_rdoc_files:
63
- - History.txt
64
- - LICENSE.txt
65
- - Manifest.txt
66
- - README.txt
22
+ version: 1.5.0
23
+ version:
24
+ description: Hai! icanhasaudio? is an interface to lame for decoding ur MP3s. I iz in ur computer. Decodin ur mp3s. Whatevs! I also decodin ur OGGz! I kin also encodin' ur WAV and AIFF to mp3z! == SYNOPSYS ROFLOL require 'icanhasaudio' reader = Audio::MPEG::Decoder.new File.open(ARGV[0], 'rb') { |input_lol| File.open(ARGV[1], 'wb') { |output_lol| reader.decode(input_lol, output_lol) } }
25
+ email: aaronp@rubyforge.org
67
26
  executables: []
27
+
68
28
  extensions:
69
- - ext/extconf.rb
29
+ - ext/extconf.rb
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - LICENSE.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ files:
36
+ - History.txt
37
+ - LICENSE.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - examples/decoder.rb
42
+ - examples/encoder.rb
43
+ - examples/kexp.rb
44
+ - ext/decoder.c
45
+ - ext/decoder.h
46
+ - ext/extconf.rb
47
+ - ext/get_audio.c
48
+ - ext/get_audio.h
49
+ - ext/icanhasaudio.c
50
+ - ext/icanhasaudio.h
51
+ - ext/mpeg_encoder.c
52
+ - ext/mpeg_encoder.h
53
+ - ext/rb_ogg.c
54
+ - ext/rb_wav.c
55
+ - ext/rb_wav.h
56
+ - ext/syncword.c
57
+ - ext/syncword.h
58
+ - lib/icanhasaudio/mpeg.rb
59
+ - lib/icanhasaudio/mpeg/encoder.rb
60
+ - lib/icanhasaudio/ogg.rb
61
+ - test/assets/testcase.wav
62
+ - test/test_mpeg_encoder.rb
63
+ has_rdoc: true
64
+ homepage: http://seattlerb.rubyforge.org/
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --main
68
+ - README.txt
69
+ require_paths:
70
+ - lib
71
+ - ext
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
70
84
  requirements: []
71
- dependencies:
72
- - !ruby/object:Gem::Dependency
73
- name: hoe
74
- version_requirement:
75
- version_requirements: !ruby/object:Gem::Version::Requirement
76
- requirements:
77
- -
78
- - ">="
79
- - !ruby/object:Gem::Version
80
- version: 1.2.2
81
- version:
85
+
86
+ rubyforge_project: seattlerb
87
+ rubygems_version: 1.0.1
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: icanhasaudio is a lame/vorbis wrapper for decoding ur mp3s and ur oggs.
91
+ test_files:
92
+ - test/test_mpeg_encoder.rb