icanhasaudio 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ == 0.0.1 / 2007-07-10
2
+
3
+ * 1 major enhancement
4
+ * I can has birfday!
5
+
@@ -0,0 +1,340 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Library General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License
307
+ along with this program; if not, write to the Free Software
308
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
309
+
310
+
311
+ Also add information on how to contact you by electronic and paper mail.
312
+
313
+ If the program is interactive, make it output a short notice like this
314
+ when it starts in an interactive mode:
315
+
316
+ Gnomovision version 69, Copyright (C) year name of author
317
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318
+ This is free software, and you are welcome to redistribute it
319
+ under certain conditions; type `show c' for details.
320
+
321
+ The hypothetical commands `show w' and `show c' should show the appropriate
322
+ parts of the General Public License. Of course, the commands you use may
323
+ be called something other than `show w' and `show c'; they could even be
324
+ mouse-clicks or menu items--whatever suits your program.
325
+
326
+ You should also get your employer (if you work as a programmer) or your
327
+ school, if any, to sign a "copyright disclaimer" for the program, if
328
+ necessary. Here is a sample; alter the names:
329
+
330
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
+
333
+ <signature of Ty Coon>, 1 April 1989
334
+ Ty Coon, President of Vice
335
+
336
+ This General Public License does not permit incorporating your program into
337
+ proprietary programs. If your program is a subroutine library, you may
338
+ consider it more useful to permit linking proprietary applications with the
339
+ library. If this is what you want to do, use the GNU Library General
340
+ Public License instead of this License.
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ examples/decoder.rb
7
+ examples/kexp.rb
8
+ ext/decoder.c
9
+ ext/decoder.h
10
+ ext/extconf.rb
11
+ ext/get_audio.c
12
+ ext/get_audio.h
13
+ ext/icanhasaudio.c
14
+ ext/syncword.c
15
+ ext/syncword.h
@@ -0,0 +1,44 @@
1
+ = Audio::MPEG
2
+
3
+ http://seattlerb.rubyforge.org/
4
+
5
+ == DESCRIPTION. LULZ
6
+
7
+ Hai! icanhasaudio? is an interface to lame for decoding ur MP3s. I iz in ur
8
+ computer. Decodin ur mp3s.
9
+
10
+ == SYNOPSYS ROFLOL
11
+
12
+ require 'icanhasaudio'
13
+
14
+ reader = Audio::MPEG::Decoder.new
15
+ File.open(ARGV[0], 'rb') { |input_lol|
16
+ File.open(ARGV[1], 'wb') { |output_lol|
17
+ reader.decode(input_lol, output_lol)
18
+ }
19
+ }
20
+
21
+ Or even smaller:
22
+
23
+ reader = Audio::MPEG::Decoder.new
24
+ reader.decode(File.open(ARGV[0], 'rb'), File.open(ARGV[1], 'wb'))
25
+
26
+ == PROBLEMS
27
+
28
+ Currently only decodes MP3 data. Plus many other problems.... YYMV. LOL.
29
+ Not laugh plz!
30
+
31
+ == DEPENDENSEEZ
32
+
33
+ Make sure lame is installed on ur 'puter.
34
+
35
+ == CREDITZ
36
+
37
+ Thanx Ryan for mah name! Also, most of this code was taken from the lame
38
+ front end. So thank you to the lame team!
39
+
40
+ == LICENSE
41
+
42
+ GPL. See LICENSE.txt
43
+
44
+ KTHX BAI!
@@ -0,0 +1,15 @@
1
+ require 'hoe'
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
4
+
5
+ Hoe.new('icanhasaudio', '0.0.1') do |p|
6
+ p.rubyforge_name = 'seattlerb'
7
+ p.author = 'Aaron Patterson'
8
+ p.email = 'aaronp@rubyforge.org'
9
+ p.summary = "icanhasaudio is a wrappers lame for decoding ur mp3s."
10
+ p.description = p.paragraphs_of('README.txt', 3..6).join("\n\n")
11
+ p.url = p.paragraphs_of('README.txt', 1).first.strip
12
+ p.changes = p.paragraphs_of('History.txt', 0..2).join("\n\n")
13
+ p.spec_extras = { :extensions => ['ext/extconf.rb'] }
14
+ end
15
+
@@ -0,0 +1,8 @@
1
+ require 'icanhasaudio'
2
+
3
+ reader = Audio::MPEG::Decoder.new
4
+ File.open(ARGV[0], 'rb') { |mp3|
5
+ File.open(ARGV[1], 'wb') { |out|
6
+ reader.decode(mp3, out);
7
+ }
8
+ }
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'raop'
3
+ require 'icanhasaudio'
4
+ require 'socket'
5
+
6
+ rd, wr = IO.pipe
7
+ puts Audio::MPEG::Decoder.lame_version
8
+
9
+ decoder = Thread.new(rd, wr) { |read, write|
10
+ reader = Audio::MPEG::Decoder.new
11
+ socket = TCPSocket.new('kexp-mp3-128k.cac.washington.edu', '8000')
12
+ socket.puts("GET / HTTP/1.0\r\n\r\n")
13
+ until(socket.readline == "\r\n"); end
14
+ reader.decode(socket, write);
15
+ write.close
16
+ }
17
+
18
+ sleep 2
19
+
20
+ raop = Net::RAOP::Client.new('192.168.1.173')
21
+ raop.connect
22
+ raop.play rd
23
+ raop.disconnect
24
+ rd.close
25
+
26
+ decoder.join
27
+
@@ -0,0 +1,105 @@
1
+ #include <ruby.h>
2
+ #include <lame/lame.h>
3
+ #include <assert.h>
4
+ #include "decoder.h"
5
+ #include "get_audio.h"
6
+
7
+ int
8
+ lame_decoder(VALUE self, VALUE infile, VALUE outf, mp3data_struct * mp3data)
9
+ {
10
+ lame_global_flags * gfp;
11
+ short int Buffer[2][1152];
12
+ int iread;
13
+ double wavsize;
14
+ int i;
15
+ int tmp_num_channels;
16
+ int skip;
17
+
18
+ Data_Get_Struct(self, lame_global_flags, gfp);
19
+ tmp_num_channels = lame_get_num_channels( gfp );
20
+
21
+ skip = lame_get_encoder_delay(gfp)+528+1;
22
+
23
+ /* FIXME: Not sure if necessary
24
+ if ( 0 == disable_wav_header )
25
+ */
26
+ WriteWaveHeader(outf, 0x7FFFFFFF, lame_get_in_samplerate( gfp ),
27
+ tmp_num_channels,
28
+ 16);
29
+
30
+ /* unknown size, so write maximum 32 bit signed value */
31
+
32
+ wavsize = -skip;
33
+ mp3data->totalframes = mp3data->nsamp / mp3data->framesize;
34
+
35
+ assert(tmp_num_channels >= 1 && tmp_num_channels <= 2);
36
+
37
+ do {
38
+ char BitBuffer16[1152 * 4];
39
+ int bit_16_i = 0;
40
+ int total = 0;
41
+ iread = get_audio16(self, infile, Buffer, mp3data);
42
+ mp3data->framenum += iread / mp3data->framesize;
43
+ wavsize += iread;
44
+
45
+ memset(&BitBuffer16, 0, 1152 * 4);
46
+
47
+ skip -= (i = skip < iread ? skip : iread); /* 'i' samples are to skip in this frame */
48
+
49
+ //printf("Writing: %d\n", mp3data->framenum);
50
+ for (; i < iread; i++) {
51
+ /*
52
+ if ( disable_wav_header ) {
53
+ WriteFunction(outf, (char *) &Buffer[0][i], sizeof(short));
54
+ if (tmp_num_channels == 2)
55
+ WriteFunction(outf, (char *) &Buffer[1][i], sizeof(short));
56
+ }
57
+ else { */
58
+
59
+ /* Write the 0 channel */
60
+ BitBuffer16[bit_16_i] = Buffer[0][i] & 0xFF;
61
+ BitBuffer16[bit_16_i + 1] = ((Buffer[0][i] >> 8) & 0xFF);
62
+
63
+ if (tmp_num_channels == 2) {
64
+ BitBuffer16[bit_16_i + 2] = Buffer[1][i] & 0xFF;
65
+ BitBuffer16[bit_16_i + 3] = ((Buffer[1][i] >> 8) & 0xFF);
66
+ bit_16_i += 4;
67
+ } else {
68
+ bit_16_i += 2;
69
+ }
70
+
71
+ /*
72
+ Write16BitsLowHigh(outf, Buffer[0][i]);
73
+ if (tmp_num_channels == 2)
74
+ Write16BitsLowHigh(outf, Buffer[1][i]);
75
+ */
76
+ /* } */
77
+ }
78
+ rb_funcall(outf, rb_intern("write"), 1, rb_str_new(BitBuffer16, bit_16_i));
79
+ } while (iread);
80
+
81
+ i = (16 / 8) * tmp_num_channels;
82
+ assert(i > 0);
83
+ if (wavsize <= 0) {
84
+ wavsize = 0;
85
+ }
86
+ else if (wavsize > 0xFFFFFFD0 / i) {
87
+ wavsize = 0xFFFFFFD0;
88
+ }
89
+ else {
90
+ wavsize *= i;
91
+ }
92
+
93
+ if(rb_respond_to(outf, rb_intern("seek")) == Qtrue) {
94
+ rb_funcall( outf,
95
+ rb_intern("seek"),
96
+ 2,
97
+ INT2NUM(0),
98
+ rb_const_get(rb_cIO, rb_intern("SEEK_SET")) );
99
+ WriteWaveHeader(outf, (int)wavsize, lame_get_in_samplerate(gfp),
100
+ tmp_num_channels, 16);
101
+ }
102
+
103
+ return 0;
104
+ }
105
+
@@ -0,0 +1,3 @@
1
+ int
2
+ lame_decoder(VALUE self, VALUE infile, VALUE outf, mp3data_struct * mp3data);
3
+
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ have_header("lame/lame.h")
4
+ have_library("mp3lame")
5
+ dir_config('icanhasaudio')
6
+ create_makefile('icanhasaudio')
@@ -0,0 +1,233 @@
1
+ #include <ruby.h>
2
+ #include <assert.h>
3
+ #include <lame/lame.h>
4
+ #include "get_audio.h"
5
+
6
+ #define MAX_U_32_NUM 0xFFFFFFFF
7
+
8
+ static int
9
+ get_audio_common(VALUE self, VALUE musicin,
10
+ int buffer[2][1152], short buffer16[2][1152],
11
+ mp3data_struct * mp3data);
12
+
13
+ static int
14
+ read_samples_mp3(VALUE self, VALUE musicin,
15
+ short int mpg123pcm[2][1152], int stereo, mp3data_struct * mp3data);
16
+
17
+ int
18
+ lame_decode_fromfile(VALUE file, short pcm_l[], short pcm_r[],
19
+ mp3data_struct * mp3data);
20
+
21
+ static void
22
+ Write16BitsLowHigh(VALUE file, int i) {
23
+ rb_funcall(file, rb_intern("putc"), 1, INT2NUM(i & 0xFF));
24
+ rb_funcall(file, rb_intern("putc"), 1, INT2NUM((i >> 8) & 0xFF));
25
+ }
26
+
27
+ void
28
+ Write32BitsLowHigh(VALUE fp, int i)
29
+ {
30
+ Write16BitsLowHigh(fp,(int)(i&0xffffL));
31
+ Write16BitsLowHigh(fp,(int)((i>>16)&0xffffL));
32
+ }
33
+
34
+ /*
35
+ get_audio16 - behave as the original get_audio function, with a limited
36
+ 16 bit per sample output
37
+ */
38
+ int
39
+ get_audio16(VALUE self, VALUE musicin, short buffer[2][1152],
40
+ mp3data_struct * mp3data)
41
+ {
42
+ return( get_audio_common( self, musicin, NULL, buffer, mp3data ) );
43
+ }
44
+
45
+ /************************************************************************
46
+ get_audio_common - central functionality of get_audio*
47
+ in: gfp
48
+ buffer output to the int buffer or 16-bit buffer
49
+ out: buffer int output (if buffer != NULL)
50
+ buffer16 16-bit output (if buffer == NULL)
51
+ returns: samples read
52
+ note: either buffer or buffer16 must be allocated upon call
53
+ */
54
+ static int
55
+ get_audio_common(VALUE self, VALUE musicin,
56
+ int buffer[2][1152], short buffer16[2][1152],
57
+ mp3data_struct * mp3data)
58
+ {
59
+ lame_global_flags *gfp;
60
+ int num_channels;
61
+ short buf_tmp16[2][1152];
62
+ int samples_read;
63
+ int framesize;
64
+ int samples_to_read;
65
+ unsigned int tmp_num_samples;
66
+ int i;
67
+
68
+ Data_Get_Struct(self, lame_global_flags, gfp);
69
+ num_channels = lame_get_num_channels( gfp );
70
+
71
+ /*
72
+ * NOTE: LAME can now handle arbritray size input data packets,
73
+ * so there is no reason to read the input data in chuncks of
74
+ * size "framesize". EXCEPT: the LAME graphical frame analyzer
75
+ * will get out of sync if we read more than framesize worth of data.
76
+ */
77
+
78
+ samples_to_read = framesize = lame_get_framesize(gfp);
79
+ assert(framesize <= 1152);
80
+
81
+ /* get num_samples */
82
+ tmp_num_samples = lame_get_num_samples( gfp );
83
+
84
+ if( buffer != NULL )
85
+ samples_read = read_samples_mp3( self, musicin,
86
+ buf_tmp16, num_channels, mp3data );
87
+ else
88
+ samples_read = read_samples_mp3( self, musicin,
89
+ buffer16, num_channels, mp3data );
90
+
91
+ if( buffer != NULL ) {
92
+ for( i = samples_read; --i >= 0; )
93
+ buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16);
94
+ if( num_channels == 2 ) {
95
+ for( i = samples_read; --i >= 0; )
96
+ buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16);
97
+ } else if( num_channels == 1 ) {
98
+ memset( buffer[1], 0, samples_read * sizeof(int) );
99
+ } else
100
+ assert(0);
101
+ }
102
+
103
+
104
+ /* if num_samples = MAX_U_32_NUM, then it is considered infinitely long.
105
+ Don't count the samples */
106
+ /*
107
+ if ( tmp_num_samples != MAX_U_32_NUM )
108
+ num_samples_read += samples_read;
109
+ */
110
+
111
+ return samples_read;
112
+ }
113
+
114
+ static int
115
+ read_samples_mp3(VALUE self, VALUE musicin,
116
+ short int mpg123pcm[2][1152], int stereo, mp3data_struct * mp3data)
117
+ {
118
+ int out;
119
+ lame_global_flags * gfp;
120
+
121
+ Data_Get_Struct(self, lame_global_flags, gfp);
122
+
123
+ out =
124
+ lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1],
125
+ mp3data);
126
+ /*
127
+ * out < 0: error, probably EOF
128
+ * out = 0: not possible with lame_decode_fromfile() ???
129
+ * out > 0: number of output samples
130
+ */
131
+ if (out < 0) {
132
+ memset(mpg123pcm, 0, sizeof(**mpg123pcm) * 2 * 1152);
133
+ return 0;
134
+ }
135
+
136
+ if ( lame_get_num_channels( gfp ) != mp3data->stereo)
137
+ rb_raise(rb_eRuntimeError, "Error: number of channels has changed");
138
+
139
+ if ( lame_get_in_samplerate( gfp ) != mp3data->samplerate)
140
+ rb_raise(rb_eRuntimeError, "Error: sample frequency has changed");
141
+
142
+ return out;
143
+ }
144
+
145
+
146
+ void
147
+ WriteWaveHeader(VALUE fp, const int pcmbytes,
148
+ const int freq, const int channels, const int bits)
149
+ {
150
+ int bytes = (bits + 7) / 8;
151
+
152
+ /* quick and dirty, but documented */
153
+ rb_funcall(fp, rb_intern("write"), 1, rb_str_new2("RIFF"));
154
+ Write32BitsLowHigh(fp, pcmbytes + 44 - 8); /* length in bytes without header */
155
+ rb_funcall(fp, rb_intern("write"), 1, rb_str_new2("WAVEfmt "));
156
+ Write32BitsLowHigh(fp, 2 + 2 + 4 + 4 + 2 + 2); /* length of PCM format declaration area */
157
+ Write16BitsLowHigh(fp, 1); /* is PCM? */
158
+ Write16BitsLowHigh(fp, channels); /* number of channels */
159
+ Write32BitsLowHigh(fp, freq); /* sample frequency in [Hz] */
160
+ Write32BitsLowHigh(fp, freq * channels * bytes); /* bytes per second */
161
+ Write16BitsLowHigh(fp, channels * bytes); /* bytes per sample time */
162
+ Write16BitsLowHigh(fp, bits); /* bits per sample */
163
+ rb_funcall(fp, rb_intern("write"), 1, rb_str_new2("data"));
164
+ Write32BitsLowHigh(fp, pcmbytes); /* length in bytes of raw PCM data */
165
+ }
166
+
167
+ /*
168
+ For lame_decode_fromfile: return code
169
+ -1 error
170
+ n number of samples output. either 576 or 1152 depending on MP3 file.
171
+
172
+
173
+ For lame_decode1_headers(): return code
174
+ -1 error
175
+ 0 ok, but need more data before outputing any samples
176
+ n number of samples output. either 576 or 1152 depending on MP3 file.
177
+ */
178
+ int
179
+ lame_decode_fromfile(VALUE file, short pcm_l[], short pcm_r[],
180
+ mp3data_struct * mp3data)
181
+ {
182
+ int ret = 0;
183
+ unsigned char buf[1024];
184
+ VALUE nread;
185
+
186
+ memset(buf, 0, 1024);
187
+ /* first see if we still have data buffered in the decoder: */
188
+ ret = lame_decode1_headers(buf, 0, pcm_l, pcm_r, mp3data);
189
+
190
+ if (ret!=0) return ret;
191
+
192
+ /* read until we get a valid output frame */
193
+ while (1) {
194
+ VALUE str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(1024));
195
+
196
+
197
+ /*
198
+ printf("tell: %d\n", NUM2INT(rb_funcall(file, rb_intern("tell"), 0)));
199
+ */
200
+
201
+ if (str == Qnil) {
202
+ /* we are done reading the file, but check for buffered data */
203
+ /*
204
+ int j;
205
+ printf("####################################################\n");
206
+ for(j = 0; j < 1024; j++) {
207
+ printf("%d\n", buf[j]);
208
+ }
209
+ printf("####################################################\n");
210
+ printf("tell: %d\n", NUM2INT(rb_funcall(file, rb_intern("tell"), 0)));
211
+ */
212
+ ret = lame_decode1_headers(buf, 0, pcm_l, pcm_r, mp3data);
213
+ if (ret<=0) {
214
+ lame_decode_exit(); /* release mp3decoder memory */
215
+ return -1; /* done with file */
216
+ }
217
+ break;
218
+ }
219
+
220
+ nread = rb_funcall(str, rb_intern("length"), 0);
221
+ memcpy(buf, StringValuePtr(str), NUM2INT(nread));
222
+
223
+ ret = lame_decode1_headers(buf, NUM2INT(nread), pcm_l, pcm_r, mp3data);
224
+ if (ret == -1) {
225
+ printf("oh shit 2\n");
226
+ lame_decode_exit(); /* release mp3decoder memory */
227
+ return -1;
228
+ }
229
+ if(ret > 0) break;
230
+ }
231
+ return ret;
232
+ }
233
+
@@ -0,0 +1,8 @@
1
+ #define MAX_U_32_NUM 0xFFFFFFFF
2
+ int
3
+ get_audio16(VALUE self, VALUE musicin, short buffer[2][1152],
4
+ mp3data_struct * mp3data);
5
+
6
+ void
7
+ WriteWaveHeader(VALUE fp, const int pcmbytes,
8
+ const int freq, const int channels, const int bits);
@@ -0,0 +1,165 @@
1
+ /*
2
+ * Most of this code was take from the lame front end. So thank you to the
3
+ * lame team! The good parts are theirs, the bad parts are mine.
4
+ *
5
+ * The rest of it is (c) 2007 Aaron Patterson <aaronp@tenderlovemaking.com>
6
+ *
7
+ * Released under the GPL
8
+ */
9
+ #include <ruby.h>
10
+ #include <lame/lame.h>
11
+ #include <dlfcn.h>
12
+ #include "syncword.h"
13
+ #include "decoder.h"
14
+ #include "get_audio.h"
15
+
16
+ static VALUE rb_mAudio;
17
+ static VALUE rb_mMpeg;
18
+ static VALUE rb_cDecoder;
19
+
20
+ static void reader_mark(lame_global_flags * lgf) {}
21
+ static void reader_free(lame_global_flags * gfp) {
22
+ lame_close(gfp);
23
+ }
24
+
25
+ /*
26
+ * call-seq:
27
+ * Audio::MPEG::Decoder.new
28
+ *
29
+ * Returns a new MPEG Decoder object.
30
+ */
31
+ static VALUE
32
+ reader_allocate(VALUE klass) {
33
+ int i = 0;
34
+ lame_global_flags * gfp = lame_init();
35
+ lame_set_decode_only(gfp, 1);
36
+ i = lame_init_params(gfp);
37
+
38
+ if(i < 0) {
39
+ rb_raise(rb_eRuntimeError, "Fatal error during initialization.\n");
40
+ }
41
+ lame_decode_init();
42
+ return Data_Wrap_Struct(klass, reader_mark, reader_free, gfp);
43
+ }
44
+
45
+ /*
46
+ * call-seq:
47
+ * Audio::MPEG::Decoder.lame_version
48
+ *
49
+ * Returns the version of lame you are using.
50
+ */
51
+ static VALUE method_lame_version(VALUE klass) {
52
+ const char * version = get_lame_version();
53
+ return rb_str_new(version, strlen(version));
54
+ }
55
+
56
+ static int lame_decode_initfile(VALUE file, mp3data_struct * mp3data) {
57
+ unsigned char * buf;
58
+ VALUE str;
59
+ int len = 4;
60
+ int enc_delay;
61
+ int enc_padding;
62
+ int ret;
63
+ short int pcm_l[1152], pcm_r[1152];
64
+
65
+ str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
66
+ buf = StringValuePtr(str);
67
+ if(buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
68
+ len = 6;
69
+ str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
70
+ buf = StringValuePtr(str);
71
+
72
+ buf[2] &= 127; buf[3] &= 127; buf[4] &= 127; buf[5] &= 127;
73
+ len = (((((buf[2] << 7) + buf[3]) << 7) + buf[4]) << 7) + buf[5];
74
+
75
+ rb_funcall( file,
76
+ rb_intern("read"),
77
+ 1,
78
+ INT2NUM(len));
79
+
80
+ len = 4;
81
+ str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
82
+ buf = StringValuePtr(str);
83
+
84
+ /* Check for Album ID */
85
+ if(0 == rb_str_cmp(str, rb_str_new2("AiD\1"))) {
86
+ /* FIXME */
87
+ rb_raise(rb_eRuntimeError, "Found Album ID.\n");
88
+ }
89
+
90
+ while (!is_syncword_mp123(buf)) {
91
+ int i;
92
+ for(i = 0; i < len - 1; i++) {
93
+ buf[i] = buf[i + 1];
94
+ }
95
+ buf[len - 1] = NUM2INT(rb_funcall(file, rb_intern("getc"), 0));
96
+ }
97
+
98
+ if ((buf[2] & 0xF0) == 0) {
99
+ printf("Input file is freeformat\n");
100
+ }
101
+
102
+ ret = lame_decode1_headersB(buf, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);
103
+ if(ret == -1)
104
+ rb_raise(rb_eRuntimeError, "Decode headers failed.\n");
105
+
106
+ while(!mp3data->header_parsed) {
107
+ str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(100));
108
+ buf = StringValuePtr(str);
109
+ ret = lame_decode1_headersB(buf, 100, pcm_l, pcm_r, mp3data,&enc_delay,&enc_padding);
110
+ if(ret == -1)
111
+ rb_raise(rb_eRuntimeError, "Decode headers failed.\n");
112
+ }
113
+
114
+ if(mp3data->totalframes > 0) {
115
+ } else {
116
+ mp3data->nsamp = MAX_U_32_NUM;
117
+ }
118
+ }
119
+ return 0;
120
+ }
121
+
122
+ /*
123
+ * call-seq:
124
+ * decoder.decode(input_io, output_io)
125
+ *
126
+ * Decode the input IO and write it to the output IO.
127
+ */
128
+ static VALUE method_lame_decode(VALUE self, VALUE file, VALUE outf) {
129
+ mp3data_struct mp3data;
130
+ lame_global_flags * gfp;
131
+
132
+ memset(&mp3data, 0, sizeof(mp3data_struct));
133
+ lame_decode_initfile(file, &mp3data);
134
+
135
+ Data_Get_Struct (self, lame_global_flags, gfp);
136
+
137
+ rb_iv_set(self, "@stereo", INT2NUM(mp3data.stereo));
138
+ rb_iv_set(self, "@samplerate", INT2NUM(mp3data.samplerate));
139
+ rb_iv_set(self, "@bitrate", INT2NUM(mp3data.bitrate));
140
+ rb_iv_set(self, "@mode", INT2NUM(mp3data.mode));
141
+ rb_iv_set(self, "@mode_ext", INT2NUM(mp3data.mode_ext));
142
+ rb_iv_set(self, "@framesize", INT2NUM(mp3data.framesize));
143
+
144
+ lame_decoder(self, file, outf, &mp3data);
145
+
146
+ return Qnil;
147
+ }
148
+
149
+ void Init_icanhasaudio() {
150
+ rb_mAudio = rb_define_module("Audio");
151
+ rb_mMpeg = rb_define_module_under(rb_mAudio, "MPEG");
152
+ rb_cDecoder = rb_define_class_under(rb_mMpeg, "Decoder", rb_cObject);
153
+ /* VERSION = '0.0.1' */
154
+ rb_define_const(rb_cDecoder, "VERSION", rb_str_new2("0.0.1"));
155
+ rb_define_singleton_method(
156
+ rb_cDecoder,
157
+ "lame_version",
158
+ method_lame_version,
159
+ 0
160
+ );
161
+
162
+ rb_define_alloc_func(rb_cDecoder, reader_allocate);
163
+ rb_define_method(rb_cDecoder, "decode", method_lame_decode, 2);
164
+ }
165
+
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Taken from lame, get_audio.c
3
+ */
4
+
5
+ int is_syncword_mp123(const void *const headerptr)
6
+ {
7
+ const unsigned char *const p = headerptr;
8
+ static const char abl2[16] =
9
+ { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 };
10
+
11
+ if ((p[0] & 0xFF) != 0xFF)
12
+ return 0; /* first 8 bits must be '1' */
13
+ if ((p[1] & 0xE0) != 0xE0)
14
+ return 0; /* next 3 bits are also */
15
+ if ((p[1] & 0x18) == 0x08)
16
+ return 0; /* no MPEG-1, -2 or -2.5 */
17
+ if ((p[1] & 0x06) == 0x00)
18
+ return 0; /* no Layer I, II and III */
19
+ #ifndef USE_LAYER_1
20
+ if ((p[1] & 0x06) == 0x03*2)
21
+ return 0; /* layer1 is not supported */
22
+ #endif
23
+ #ifndef USE_LAYER_2
24
+ if ((p[1] & 0x06) == 0x02*2)
25
+ return 0; /* layer1 is not supported */
26
+ #endif
27
+ /*
28
+ if (!(((p[1] & 0x06) == 0x03*2 && input_format == sf_mp1)
29
+ || ((p[1] & 0x06) == 0x02*2 && input_format == sf_mp2)
30
+ || ((p[1] & 0x06) == 0x01*2 && input_format == sf_mp3)))
31
+ */
32
+ if(!(p[1] & 0x06) == 0x01*2)
33
+ return 0; /* imcompatible layer with input file format */
34
+ if ((p[2] & 0xF0) == 0xF0)
35
+ return 0; /* bad bitrate */
36
+ if ((p[2] & 0x0C) == 0x0C)
37
+ return 0; /* no sample frequency with (32,44.1,48)/(1,2,4) */
38
+ if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04
39
+ && abl2[p[2] >> 4] & (1 << (p[3] >> 6)))
40
+ return 0;
41
+ if ((p[3] & 3) == 2)
42
+ return 0; /* reserved enphasis mode */
43
+ return 1;
44
+ }
45
+
@@ -0,0 +1,3 @@
1
+
2
+ int is_syncword_mp123(const void *const headerptr);
3
+
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: icanhasaudio
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-07-11 00:00:00 -07:00
8
+ summary: icanhasaudio is a wrappers lame for decoding ur mp3s.
9
+ require_paths:
10
+ - ext
11
+ email: aaronp@rubyforge.org
12
+ homepage: http://seattlerb.rubyforge.org/
13
+ rubyforge_project: seattlerb
14
+ description: "Hai! icanhasaudio? is an interface to lame for decoding ur MP3s. I iz in ur
15
+ computer. Decodin ur mp3s. == SYNOPSYS ROFLOL require 'icanhasaudio' reader =
16
+ Audio::MPEG::Decoder.new File.open(ARGV[0], 'rb') { |input_lol|
17
+ File.open(ARGV[1], 'wb') { |output_lol| reader.decode(input_lol, output_lol) }
18
+ }"
19
+ autorequire:
20
+ default_executable:
21
+ bindir: bin
22
+ has_rdoc: true
23
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
24
+ requirements:
25
+ -
26
+ - ">"
27
+ - !ruby/object:Gem::Version
28
+ version: 0.0.0
29
+ version:
30
+ platform: ruby
31
+ signing_key:
32
+ cert_chain:
33
+ post_install_message:
34
+ authors:
35
+ - Aaron Patterson
36
+ files:
37
+ - History.txt
38
+ - LICENSE.txt
39
+ - Manifest.txt
40
+ - README.txt
41
+ - Rakefile
42
+ - examples/decoder.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/syncword.c
51
+ - ext/syncword.h
52
+ test_files: []
53
+ rdoc_options:
54
+ - "--main"
55
+ - README.txt
56
+ extra_rdoc_files:
57
+ - History.txt
58
+ - LICENSE.txt
59
+ - Manifest.txt
60
+ - README.txt
61
+ executables: []
62
+ extensions:
63
+ - ext/extconf.rb
64
+ requirements: []
65
+ dependencies:
66
+ - !ruby/object:Gem::Dependency
67
+ name: hoe
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Version::Requirement
70
+ requirements:
71
+ -
72
+ - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.2.1
75
+ version: