icanhasaudio 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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