catori 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/VERSION +1 -0
  2. data/bin/catori +9 -0
  3. data/changelog.txt +3 -0
  4. data/construir +3 -0
  5. data/crear_vista.sql +8 -0
  6. data/ext/audiofile/MANIFEST +8 -0
  7. data/ext/audiofile/README +11 -0
  8. data/ext/audiofile/audiofile.c +833 -0
  9. data/ext/audiofile/audiofile.rd +265 -0
  10. data/ext/audiofile/depend +0 -0
  11. data/ext/audiofile/extconf.rb +8 -0
  12. data/ext/audiofile/fail.rb +22 -0
  13. data/ext/audiofile/mkmf.log +34 -0
  14. data/ext/audiofile/test.rb +229 -0
  15. data/ext/flac/extconf.rb +5 -0
  16. data/ext/flac/flac.c +75 -0
  17. data/ext/flac/mkmf.log +12 -0
  18. data/ext/flac/test.rb +3 -0
  19. data/ext/mahoro-0.1/INSTALL +9 -0
  20. data/ext/mahoro-0.1/extconf.rb +7 -0
  21. data/ext/mahoro-0.1/mahoro.c +187 -0
  22. data/ext/mahoro-0.1/mkmf.log +24 -0
  23. data/ext/mahoro-0.1/test.rb +41 -0
  24. data/ext/mpc/extconf.rb +5 -0
  25. data/ext/mpc/id3tag.c +245 -0
  26. data/ext/mpc/id3tag.h +5 -0
  27. data/ext/mpc/mkmf.log +12 -0
  28. data/ext/mpc/mpc.c +56 -0
  29. data/ext/mpc/mpp.h +194 -0
  30. data/ext/mpc/mppdec.h +1171 -0
  31. data/ext/mpc/test.rb +3 -0
  32. data/ext/rmac/extconf.rb +7 -0
  33. data/ext/rmac/mkmf.log +22 -0
  34. data/ext/rmac/rmac.cpp +162 -0
  35. data/ext/vorbisfile/ChangeLog +11 -0
  36. data/ext/vorbisfile/README +33 -0
  37. data/ext/vorbisfile/configure +2 -0
  38. data/ext/vorbisfile/extconf.rb +9 -0
  39. data/ext/vorbisfile/mkmf.log +68 -0
  40. data/ext/vorbisfile/test.rb +78 -0
  41. data/ext/vorbisfile/vorbisfile.c +482 -0
  42. data/instalar.txt +19 -0
  43. data/install.rb +11 -0
  44. data/lib/audioinfo.rb +321 -0
  45. data/lib/catori.rb +131 -0
  46. data/lib/catori/Catalogador.rb +71 -0
  47. data/lib/catori/Db.rb +81 -0
  48. data/lib/catori/Gui.rb +52 -0
  49. data/lib/catori/Installer.rb +16 -0
  50. data/lib/catori/Query.rb +82 -0
  51. data/lib/catori/XML.rb +42 -0
  52. data/lib/catori/catori_gui.glade +340 -0
  53. data/lib/catori/catori_gui.glade.bak +340 -0
  54. data/lib/catori/catori_gui.gladep +8 -0
  55. data/lib/catori/catori_gui.gladep.bak +8 -0
  56. data/lib/catori/taglib.rb +227 -0
  57. data/lib/pixmaps/album.png +0 -0
  58. data/lib/pixmaps/artist.png +0 -0
  59. data/lib/pixmaps/cdr.png +0 -0
  60. data/lib/pixmaps/song.png +0 -0
  61. data/lib/taglib.rb +230 -0
  62. data/sql/catori_mysql.sql +68 -0
  63. data/sql/catori_pg.sql +65 -0
  64. data/tests/saw.ape +0 -0
  65. data/tests/saw.flac +0 -0
  66. data/tests/saw.mp3 +0 -0
  67. data/tests/saw.mpc +0 -0
  68. data/tests/saw.ogg +0 -0
  69. data/tests/saw.wav +0 -0
  70. data/tests/test_audioinfo.rb +43 -0
  71. metadata +217 -0
@@ -0,0 +1,3 @@
1
+ require 'mpc'
2
+
3
+ p Mpc.info("test.mpc")
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+ dir_config("mac",'/usr/include/mac','/usr/lib')
3
+ if (have_library("mac") and have_header("mac/All.h"))
4
+ create_makefile("rmac");
5
+ else
6
+ puts "Error: Can't find headers or library for libmac"
7
+ end
@@ -0,0 +1,22 @@
1
+ have_library: checking for main() in -lmac... -------------------- yes
2
+
3
+ "i686-pc-linux-gnu-gcc -o conftest -I. -I/usr/lib/ruby/1.8/i686-linux -I. -I/usr/include/mac -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -L'.' -L'/usr/lib' -Wl,-R'/usr/lib' -L'/usr/lib' -Wl,-R'/usr/lib' -L. -rdynamic -Wl,-export-dynamic -lruby18-static -lmac -ldl -lcrypt -lm -lc"
4
+ checked program was:
5
+ /* begin */
6
+ 1: /*top*/
7
+ 2: int main() { return 0; }
8
+ 3: int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; }
9
+ /* end */
10
+
11
+ --------------------
12
+
13
+ have_header: checking for mac/All.h... -------------------- yes
14
+
15
+ "i686-pc-linux-gnu-gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -I/usr/include/mac -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -o conftest.i"
16
+ checked program was:
17
+ /* begin */
18
+ 1: #include <mac/All.h>
19
+ /* end */
20
+
21
+ --------------------
22
+
@@ -0,0 +1,162 @@
1
+ /***************************************************************************************
2
+ Analyze - Sample 1
3
+ Copyright (C) 2000-2001 by Matthew T. Ashland All Rights Reserved.
4
+ Feel free to use this code in any way that you like.
5
+
6
+ This example opens an APE file and displays some basic information about it. To use it,
7
+ just type Sample 1.exe followed by a file name and it'll display information about that
8
+ file.
9
+
10
+ Notes for use in a new project:
11
+ -you need to include "MACLib.lib" in the included libraries list
12
+ -life will be easier if you set the [MAC SDK]\\Shared directory as an include
13
+ directory and an additional library input path in the project settings
14
+ -set the runtime library to "Mutlithreaded"
15
+
16
+ WARNING:
17
+ -This class driven system for using Monkey's Audio is still in development, so
18
+ I can't make any guarantees that the classes and libraries won't change before
19
+ everything gets finalized. Use them at your own risk.
20
+ ***************************************************************************************/
21
+
22
+ // includes
23
+ #include <ruby.h>
24
+
25
+ #include <stdio.h>
26
+ #include <ctype.h>
27
+ #include "All.h"
28
+ #include "GlobalFunctions.h"
29
+ #include "MACLib.h"
30
+ #include "CharacterHelper.h"
31
+ #include "APETag.h"
32
+ #define CPPVAL ( VALUE (*) (...) )
33
+ extern "C" {
34
+ static VALUE mMac;
35
+ static VALUE cInfo;
36
+ static VALUE rb_cinfo_new(VALUE self);
37
+ static VALUE rb_mac_info(VALUE module, VALUE filename);
38
+
39
+ void Init_rmac()
40
+ {
41
+ mMac = rb_define_module("Mac");
42
+ cInfo = rb_define_class_under(mMac,"Info",rb_cObject);
43
+
44
+ #define NA 16
45
+ const char *attr2[NA] =
46
+ { "version","compression_level","samplerate","bps","channels","peak","length", "filesize", "id3_tag", "ape_tag", "artist","album","title","genre","track","year"
47
+ };
48
+ for (int i = 0; i < NA; i++) {
49
+ rb_define_attr(cInfo, attr2[i], 1, 0);
50
+ }
51
+
52
+ rb_define_module_function(mMac,"info", CPPVAL rb_mac_info ,1);
53
+
54
+ }
55
+
56
+ }
57
+ VALUE rb_mac_info(VALUE module, VALUE filename) {
58
+ VALUE info=rb_class_new_instance(0,NULL,cInfo);
59
+ ///////////////////////////////////////////////////////////////////////////////
60
+ // variable declares
61
+ ///////////////////////////////////////////////////////////////////////////////
62
+ int nRetVal = 0; // generic holder for return values
63
+ char cTempBuffer[256]; ZeroMemory(&cTempBuffer[0], 256); // generic buffer for string stuff
64
+ char * pFilename = STR2CSTR(filename); // the file to open
65
+ IAPEDecompress * pAPEDecompress = NULL; // APE interface
66
+ CSmartPtr<wchar_t> spInput;
67
+ spInput.Assign(GetUTF16FromANSI(pFilename), TRUE);
68
+
69
+ //*
70
+ ///////////////////////////////////////////////////////////////////////////////
71
+ // open the file and error check
72
+ ///////////////////////////////////////////////////////////////////////////////
73
+ pAPEDecompress = CreateIAPEDecompress(spInput, &nRetVal);
74
+ if (pAPEDecompress == NULL)
75
+ {
76
+ rb_raise(rb_eIOError, "Error opening APE file. (error code %d)", nRetVal);
77
+ }
78
+
79
+
80
+ ///////////////////////////////////////////////////////////////////////////////
81
+ // display some information about the file
82
+ ///////////////////////////////////////////////////////////////////////////////
83
+ // file format information
84
+ char ape_version[5];
85
+ sprintf(ape_version,"%02.3f",float(pAPEDecompress->GetInfo(APE_INFO_FILE_VERSION)/1000.0));
86
+ rb_iv_set(info,"@version", rb_str_new2(ape_version));
87
+ switch (pAPEDecompress->GetInfo(APE_INFO_COMPRESSION_LEVEL))
88
+ {
89
+ case COMPRESSION_LEVEL_FAST: rb_iv_set(info,"@compression_level",rb_str_new2("Fast")); break;
90
+ case COMPRESSION_LEVEL_NORMAL: rb_iv_set(info,"@compression_level",rb_str_new2("Normal")); break;
91
+ case COMPRESSION_LEVEL_HIGH: rb_iv_set(info,"@compression_level",rb_str_new2("High")); break;
92
+ case COMPRESSION_LEVEL_EXTRA_HIGH: rb_iv_set(info,"@compression_level",rb_str_new2("Extra High")); break;
93
+ }
94
+
95
+ // audio format information
96
+ rb_iv_set(info,"@samplerate",INT2FIX(pAPEDecompress->GetInfo(APE_INFO_SAMPLE_RATE)));
97
+ rb_iv_set(info,"@bps",INT2FIX(pAPEDecompress->GetInfo(APE_INFO_BITS_PER_SAMPLE)));
98
+ rb_iv_set(info,"@channels",INT2FIX(pAPEDecompress->GetInfo(APE_INFO_CHANNELS)));
99
+ rb_iv_set(info,"@peak",INT2FIX(pAPEDecompress->GetInfo(APE_INFO_PEAK_LEVEL)));
100
+
101
+ // size and duration information
102
+ rb_iv_set(info,"@length",rb_float_new((pAPEDecompress->GetInfo(APE_INFO_LENGTH_MS) / 1000.00)));
103
+ rb_iv_set(info,"@filesize",INT2FIX(pAPEDecompress->GetInfo(APE_INFO_APE_TOTAL_BYTES)));
104
+
105
+ // tag information
106
+ CAPETag * pAPETag = (CAPETag *) pAPEDecompress->GetInfo(APE_INFO_TAG);
107
+ BOOL bHasID3Tag = pAPETag->GetHasID3Tag();
108
+ BOOL bHasAPETag = pAPETag->GetHasAPETag();
109
+ rb_iv_set(info,"@id3_tag",(bHasID3Tag?Qtrue:Qfalse));
110
+ rb_iv_set(info,"@ape_tag",(bHasAPETag?Qtrue:Qfalse));
111
+
112
+ if (bHasID3Tag || bHasAPETag)
113
+ {
114
+ if (bHasAPETag)
115
+ {
116
+ char ape_tag_version[5];
117
+ sprintf(ape_tag_version,"%05.3f",float(pAPETag->GetAPETagVersion()/1000.0));
118
+ rb_iv_set(info,"@ape_tag_version",rb_str_new2(ape_tag_version));
119
+ }
120
+ // iterate through all the tag fields
121
+ BOOL bFirst = TRUE;
122
+ CAPETagField * pTagField;
123
+ // while (pAPETag->GetNextTagField(bFirst, &pTagField))
124
+ int index = 0;
125
+ while ((pTagField = pAPETag->GetTagField(index)) != NULL)
126
+ {
127
+ bFirst = FALSE;
128
+ index ++;
129
+
130
+ // output the tag field properties (don't output huge fields like images, etc.)
131
+ if (pTagField->GetFieldValueSize() > 128)
132
+ {
133
+ //printf("\t%s: --- too much data to display ---\r\n", GetANSIFromUTF16(pTagField->GetFieldName()));
134
+ }
135
+ else
136
+ {
137
+
138
+ const wchar_t *fieldName;
139
+ const char *fieldValue;
140
+ char *value;
141
+
142
+ fieldName = pTagField->GetFieldName();
143
+ fieldValue = pTagField->GetFieldValue();
144
+ strcpy(cTempBuffer,"@");
145
+ strcat(cTempBuffer,(char *)GetUTF8FromUTF16(fieldName));
146
+ cTempBuffer[1]=tolower(cTempBuffer[1]);
147
+ rb_iv_set(info,cTempBuffer,rb_str_new2(fieldValue));
148
+ }
149
+ }
150
+ }
151
+
152
+ ///////////////////////////////////////////////////////////////////////////////
153
+ // cleanup (just delete the object
154
+ ///////////////////////////////////////////////////////////////////////////////
155
+ delete pAPEDecompress;
156
+
157
+ ///////////////////////////////////////////////////////////////////////////////
158
+ // quit
159
+ ///////////////////////////////////////////////////////////////////////////////
160
+ return info;
161
+
162
+ }
@@ -0,0 +1,11 @@
1
+ 0.2 Second release
2
+ * Now uses _one_ string as a buffer, instead of passing you one back
3
+ after each read(). I had to do this, because the GC couldn't keep
4
+ up. Thanks to the bloke who showed me his example code for this,
5
+ and the ruby-audiofile author, whose idea I eventually used.
6
+ NOTE: This means the API has changed for read() !
7
+ * Put class VorbisFile into module 'Ogg' - so now you need to use
8
+ Ogg::Vorbisfile.
9
+
10
+ 0.1 Initial relese
11
+
@@ -0,0 +1,33 @@
1
+ Ruby extension for libvorbisfile.
2
+
3
+ libvorbisfile is a decoder library provided with the Ogg Vorbis
4
+ distribution. See http://xiph.org/ogg/vorbis/ for details.
5
+
6
+ The API of this extension is virtually identical to that of
7
+ vorbisfile.h, with a couple of exceptions:
8
+
9
+ * Prefixes have been removed (ov_open -> open).
10
+ * The OggVorbis_File parameter is removed, as the VorbisFile object
11
+ encapsulates this.
12
+
13
+ You can read the vorbisfile API at the above URL.
14
+
15
+ Installation:
16
+
17
+ ./configure
18
+ make
19
+ make install
20
+
21
+ Note that you must pass an existing (and opened) IO object to
22
+ VorbisFile::open(). This means you are not restricted to files -
23
+ reading from (e.g.) a socket is fine.
24
+
25
+ See test.rb for an example.
26
+
27
+ Note that Vorbis comments are in UTF-8 and test.rb uses iconv to convert
28
+ back to latin-1. Is there a more portable way of doing this ?
29
+
30
+ Feedback welcome.
31
+
32
+ Rik Hemsley (rikkus) <rik@kde.org>
33
+
@@ -0,0 +1,2 @@
1
+ # vim: set syntax=sh
2
+ ruby extconf.rb $*
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+
3
+ exit 1 unless have_library("vorbis", "vorbis_analysis")
4
+ exit 1 unless have_library("vorbisfile", "ov_open_callbacks")
5
+
6
+ exit 1 unless have_header("vorbis/codec.h")
7
+ exit 1 unless have_header("vorbis/vorbisfile.h")
8
+
9
+ create_makefile("vorbisfile")
@@ -0,0 +1,68 @@
1
+ have_library: checking for vorbis_analysis() in -lvorbis... -------------------- yes
2
+
3
+ "i686-pc-linux-gnu-gcc -o conftest -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -L'.' -L'/usr/lib' -Wl,-R'/usr/lib' -L. -rdynamic -Wl,-export-dynamic -lruby18-static -lvorbis -ldl -lcrypt -lm -lc"
4
+ conftest.c: En la función ‘t’:
5
+ conftest.c:3: error: ‘vorbis_analysis’ no se declaró aquí (primer uso en esta función)
6
+ conftest.c:3: error: (Cada identificador no declarado solamente se reporta una vez
7
+ conftest.c:3: error: ara cada funcion en la que aparece.)
8
+ checked program was:
9
+ /* begin */
10
+ 1: /*top*/
11
+ 2: int main() { return 0; }
12
+ 3: int t() { void ((*volatile p)()); p = (void ((*)()))vorbis_analysis; return 0; }
13
+ /* end */
14
+
15
+ "i686-pc-linux-gnu-gcc -o conftest -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -L'.' -L'/usr/lib' -Wl,-R'/usr/lib' -L. -rdynamic -Wl,-export-dynamic -lruby18-static -lvorbis -ldl -lcrypt -lm -lc"
16
+ checked program was:
17
+ /* begin */
18
+ 1: /*top*/
19
+ 2: int main() { return 0; }
20
+ 3: int t() { vorbis_analysis(); return 0; }
21
+ /* end */
22
+
23
+ --------------------
24
+
25
+ have_library: checking for ov_open_callbacks() in -lvorbisfile... -------------------- yes
26
+
27
+ "i686-pc-linux-gnu-gcc -o conftest -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -L'.' -L'/usr/lib' -Wl,-R'/usr/lib' -L. -rdynamic -Wl,-export-dynamic -lvorbis -lruby18-static -lvorbisfile -lvorbis -ldl -lcrypt -lm -lc"
28
+ conftest.c: En la función ‘t’:
29
+ conftest.c:3: error: ‘ov_open_callbacks’ no se declaró aquí (primer uso en esta función)
30
+ conftest.c:3: error: (Cada identificador no declarado solamente se reporta una vez
31
+ conftest.c:3: error: ara cada funcion en la que aparece.)
32
+ checked program was:
33
+ /* begin */
34
+ 1: /*top*/
35
+ 2: int main() { return 0; }
36
+ 3: int t() { void ((*volatile p)()); p = (void ((*)()))ov_open_callbacks; return 0; }
37
+ /* end */
38
+
39
+ "i686-pc-linux-gnu-gcc -o conftest -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -L'.' -L'/usr/lib' -Wl,-R'/usr/lib' -L. -rdynamic -Wl,-export-dynamic -lvorbis -lruby18-static -lvorbisfile -lvorbis -ldl -lcrypt -lm -lc"
40
+ checked program was:
41
+ /* begin */
42
+ 1: /*top*/
43
+ 2: int main() { return 0; }
44
+ 3: int t() { ov_open_callbacks(); return 0; }
45
+ /* end */
46
+
47
+ --------------------
48
+
49
+ have_header: checking for vorbis/codec.h... -------------------- yes
50
+
51
+ "i686-pc-linux-gnu-gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -o conftest.i"
52
+ checked program was:
53
+ /* begin */
54
+ 1: #include <vorbis/codec.h>
55
+ /* end */
56
+
57
+ --------------------
58
+
59
+ have_header: checking for vorbis/vorbisfile.h... -------------------- yes
60
+
61
+ "i686-pc-linux-gnu-gcc -E -I. -I/usr/lib/ruby/1.8/i686-linux -I. -O2 -march=athlon-xp -m3dnow -msse -mfpmath=sse -mmmx -pipe -fno-strict-aliasing -fPIC conftest.c -o conftest.i"
62
+ checked program was:
63
+ /* begin */
64
+ 1: #include <vorbis/vorbisfile.h>
65
+ /* end */
66
+
67
+ --------------------
68
+
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # test.rb - part of ruby-vorbisfile
4
+ #
5
+ # Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to
9
+ # deal in the Software without restriction, including without limitation the
10
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11
+ # sell copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
+ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+
25
+ require 'iconv'
26
+ require '../../lib/vorbisfile'
27
+
28
+ $my_charset = 'utf-8'
29
+
30
+ if ARGV.empty?
31
+ $stderr.print "Usage: #{File.basename($0)} <filename> ...\n"
32
+ $stderr.print "You probably want to pipe to a program, e.g. aplay -meq\n"
33
+ exit 1
34
+ end
35
+
36
+ ARGV.each do |filename|
37
+
38
+ f = File.new(filename, "r")
39
+
40
+ if !f
41
+ $stderr.print "Can't open #{filename}\n"
42
+ next
43
+ end
44
+
45
+ vf = Ogg::VorbisFile.new
46
+
47
+ if !vf.open(f)
48
+ $stderr.print "Can't read vorbis data from #{filename}\n"
49
+ next
50
+ end
51
+ p vf.comments(-1)
52
+ comments = vf.comments(-1)
53
+
54
+ artist = comments["artist"]
55
+ title = comments["title"]
56
+
57
+ begin
58
+ artist = Iconv.iconv($my_charset, 'utf-8', artist)
59
+ rescue
60
+ artist = "Unknown artist"
61
+ end
62
+
63
+ begin
64
+ title = Iconv.iconv($my_charset, 'utf-8', title)
65
+ rescue
66
+ title = "Unknown title"
67
+ end
68
+
69
+ $stderr.print "#{artist} - #{title}\n"
70
+
71
+ buf = ""
72
+
73
+ #while vf.read(buf, 4096, false, 2, true)
74
+ # $stdout.print buf
75
+ #end
76
+
77
+ vf.close
78
+ end
@@ -0,0 +1,482 @@
1
+ /*
2
+ vorbisfile.c - part of ruby-vorbisfile
3
+
4
+ Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to
8
+ deal in the Software without restriction, including without limitation the
9
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ sell copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+
24
+ #include <stdio.h>
25
+ #include <ctype.h>
26
+ #include <string.h>
27
+
28
+ #include <ruby.h>
29
+ #include <rubysig.h>
30
+
31
+ #include <vorbis/codec.h>
32
+ #include <vorbis/vorbisfile.h>
33
+
34
+ #define LONG2FIX INT2FIX /* Ruby 1.6 :( */
35
+
36
+ static VALUE cOgg;
37
+ static VALUE cVorbisFile;
38
+
39
+ static size_t
40
+ vf_fread(ptr, size, n, stream)
41
+ void * ptr;
42
+ size_t size;
43
+ size_t n;
44
+ void * stream;
45
+ {
46
+ VALUE io = (VALUE)stream;
47
+ VALUE buf;
48
+ VALUE count = INT2FIX(size * n);
49
+ buf = rb_funcall3(io, rb_intern("read"), 1, &count);
50
+
51
+ if (Qnil == buf)
52
+ {
53
+ /* fprintf(stderr, "io.read returned nil\n"); */
54
+ return 0;
55
+ }
56
+
57
+ /* fprintf(stderr, "io.read returned a buf of size %d\n", RSTRING(buf)->len); */
58
+
59
+ memcpy(ptr, RSTRING(buf)->ptr, RSTRING(buf)->len);
60
+ return RSTRING(buf)->len;
61
+ }
62
+
63
+ static int
64
+ vf_fseek(stream, offset, whence)
65
+ void * stream;
66
+ int64_t offset;
67
+ int whence;
68
+ {
69
+ VALUE io = (VALUE)stream;
70
+ int ret = 0;
71
+
72
+ VALUE args[2];
73
+
74
+ args[0] = LONG2FIX(offset);
75
+ args[1] = INT2FIX(whence);
76
+
77
+ ret = FIX2INT(rb_funcall3(io, rb_intern("seek"), 2, args));
78
+
79
+ /*fprintf(stderr, "io.seek(%d, %d) returned %d\n", offset, whence, ret);*/
80
+
81
+ return ret;
82
+ }
83
+
84
+ static int
85
+ vf_fclose(stream)
86
+ void * stream;
87
+ {
88
+ VALUE io = (VALUE)stream;
89
+ (void) rb_funcall3(io, rb_intern("close"), 0, 0);
90
+ return 1;
91
+ }
92
+
93
+ static long
94
+ vf_ftell(stream)
95
+ void * stream;
96
+ {
97
+ VALUE io = (VALUE)stream;
98
+ long ret = 0;
99
+ ret = FIX2LONG(rb_funcall3(io, rb_intern("pos"), 0, 0));
100
+
101
+ /*fprintf(stderr, "io.pos == %d\n", ret);*/
102
+ return ret;
103
+ }
104
+
105
+ static void
106
+ vf_delete(vf)
107
+ void * vf;
108
+ {
109
+ ov_clear((OggVorbis_File *)vf);
110
+ free(vf);
111
+ }
112
+
113
+ static VALUE
114
+ vf_s_new(argc, argv, klass)
115
+ int argc;
116
+ VALUE * argv;
117
+ VALUE klass;
118
+ {
119
+ VALUE obj = Data_Wrap_Struct(klass, 0, vf_delete, 0);
120
+ rb_obj_call_init(obj, argc, argv);
121
+ return obj;
122
+ }
123
+
124
+ static VALUE
125
+ vf_initialize(argc, argv, obj)
126
+ int argc;
127
+ VALUE * argv;
128
+ VALUE obj;
129
+ {
130
+ struct OggVorbis_File * vf = 0;
131
+
132
+ vf = ALLOC(struct OggVorbis_File);
133
+ DATA_PTR(obj) = vf;
134
+ return obj;
135
+ }
136
+
137
+ static VALUE
138
+ vf_open(obj, io)
139
+ VALUE obj;
140
+ VALUE io;
141
+ {
142
+ OggVorbis_File * vf = 0;
143
+ ov_callbacks callbacks;
144
+
145
+ Data_Get_Struct(obj, OggVorbis_File, vf);
146
+
147
+ rb_iv_set(obj, "io", io);
148
+
149
+ if (Qnil == io)
150
+ return Qfalse;
151
+
152
+ callbacks.read_func = vf_fread;
153
+ callbacks.seek_func = vf_fseek;
154
+ callbacks.close_func = vf_fclose;
155
+ callbacks.tell_func = vf_ftell;
156
+
157
+ if
158
+ (
159
+ ov_open_callbacks
160
+ ((void *)io, vf, NULL, 0, callbacks) < 0
161
+ )
162
+ {
163
+ /* fprintf(stderr, "ov_open_callbacks failed\n"); */
164
+ return Qfalse;
165
+ }
166
+
167
+ /* fprintf(stderr, "ov_open_callbacks succeded\n"); */
168
+ return Qtrue;
169
+ }
170
+
171
+ static VALUE
172
+ vf_read(obj, str, count, big_endian, word_size, sgned)
173
+ VALUE obj;
174
+ VALUE str;
175
+ VALUE count;
176
+ VALUE big_endian;
177
+ VALUE word_size;
178
+ VALUE sgned;
179
+ {
180
+ OggVorbis_File * vf = 0;
181
+ char * buf = 0;
182
+ long bytes_read = 0;
183
+ int vorbisSection = 0;
184
+ VALUE ret;
185
+
186
+ Data_Get_Struct(obj, OggVorbis_File, vf);
187
+
188
+ Check_Type(str, T_STRING);
189
+
190
+ rb_str_resize(str, count);
191
+
192
+ buf = RSTRING(str)->ptr;
193
+
194
+ bytes_read =
195
+ ov_read
196
+ (
197
+ vf,
198
+ buf,
199
+ count,
200
+ (Qtrue == big_endian) ? 1 : 0,
201
+ NUM2INT(word_size),
202
+ (Qtrue == sgned) ? 1 : 0,
203
+ &vorbisSection
204
+ );
205
+
206
+ if (bytes_read > 0)
207
+ {
208
+ rb_str_resize(str, bytes_read);
209
+ return INT2NUM(bytes_read);
210
+ }
211
+ else
212
+ {
213
+ rb_str_resize(str, 0);
214
+ return Qnil;
215
+ }
216
+ }
217
+
218
+ static VALUE
219
+ vf_close(obj)
220
+ VALUE obj;
221
+ {
222
+ OggVorbis_File * vf = 0;
223
+ Data_Get_Struct(obj, OggVorbis_File, vf);
224
+ /* fprintf(stderr, "About to ov_clear %p\n", vf); */
225
+ return INT2FIX(ov_clear(vf));
226
+ }
227
+
228
+ static VALUE
229
+ vf_raw_seek(obj, pos)
230
+ VALUE obj;
231
+ VALUE pos;
232
+ {
233
+ OggVorbis_File * vf = 0;
234
+ Data_Get_Struct(obj, OggVorbis_File, vf);
235
+ return INT2FIX(ov_raw_seek(vf, NUM2LONG(pos)));
236
+ }
237
+
238
+ static VALUE
239
+ vf_pcm_seek(obj, pos, fast)
240
+ VALUE obj;
241
+ VALUE pos;
242
+ VALUE fast;
243
+ {
244
+ OggVorbis_File * vf = 0;
245
+
246
+ Data_Get_Struct(obj, OggVorbis_File, vf);
247
+
248
+ if (NUM2INT(fast))
249
+ return INT2FIX(ov_pcm_seek_page(vf, NUM2LONG(pos)));
250
+ else
251
+ return INT2FIX(ov_pcm_seek(vf, NUM2LONG(pos)));
252
+ }
253
+
254
+ static VALUE
255
+ vf_time_seek(obj, pos, fast)
256
+ VALUE obj;
257
+ VALUE pos;
258
+ VALUE fast;
259
+ {
260
+ OggVorbis_File * vf = 0;
261
+
262
+ Data_Get_Struct(obj, OggVorbis_File, vf);
263
+
264
+ if (NUM2INT(fast))
265
+ return INT2FIX(ov_time_seek_page(vf, NUM2DBL(pos)));
266
+ else
267
+ return INT2FIX(ov_time_seek(vf, NUM2DBL(pos)));
268
+ }
269
+
270
+ static VALUE
271
+ vf_raw_tell(obj, pos)
272
+ VALUE obj;
273
+ VALUE pos;
274
+ {
275
+ OggVorbis_File * vf = 0;
276
+ Data_Get_Struct(obj, OggVorbis_File, vf);
277
+ return LONG2FIX(ov_raw_tell(vf));
278
+ }
279
+
280
+ static VALUE
281
+ vf_pcm_tell(obj, pos)
282
+ VALUE obj;
283
+ VALUE pos;
284
+ {
285
+ OggVorbis_File * vf = 0;
286
+ Data_Get_Struct(obj, OggVorbis_File, vf);
287
+ return LONG2FIX(ov_pcm_tell(vf));
288
+ }
289
+
290
+ static VALUE
291
+ vf_time_tell(obj, pos)
292
+ VALUE obj;
293
+ VALUE pos;
294
+ {
295
+ OggVorbis_File * vf = 0;
296
+ Data_Get_Struct(obj, OggVorbis_File, vf);
297
+ return rb_float_new(ov_time_tell(vf));
298
+ }
299
+
300
+ static VALUE
301
+ vf_raw_total(obj, link)
302
+ VALUE obj;
303
+ VALUE link;
304
+ {
305
+ OggVorbis_File * vf = 0;
306
+ Data_Get_Struct(obj, OggVorbis_File, vf);
307
+ return LONG2FIX(ov_raw_total(vf, NUM2INT(link)));
308
+ }
309
+
310
+ static VALUE
311
+ vf_pcm_total(obj, link)
312
+ VALUE obj;
313
+ VALUE link;
314
+ {
315
+ OggVorbis_File * vf = 0;
316
+ Data_Get_Struct(obj, OggVorbis_File, vf);
317
+ return LONG2FIX(ov_pcm_total(vf, NUM2INT(link)));
318
+ }
319
+
320
+ static VALUE
321
+ vf_time_total(obj, link)
322
+ VALUE obj;
323
+ VALUE link;
324
+ {
325
+ OggVorbis_File * vf = 0;
326
+ Data_Get_Struct(obj, OggVorbis_File, vf);
327
+ return rb_float_new(ov_time_total(vf, NUM2INT(link)));
328
+ }
329
+
330
+ static VALUE
331
+ vf_channels(obj, link)
332
+ VALUE obj;
333
+ VALUE link;
334
+ {
335
+ vorbis_info * vi = 0;
336
+ OggVorbis_File * vf = 0;
337
+ Data_Get_Struct(obj, OggVorbis_File, vf);
338
+ vi = ov_info(vf, NUM2INT(link));
339
+ return INT2FIX(vi->channels);
340
+ }
341
+
342
+ static VALUE
343
+ vf_sample_rate(obj, link)
344
+ VALUE obj;
345
+ VALUE link;
346
+ {
347
+ vorbis_info * vi = 0;
348
+ OggVorbis_File * vf = 0;
349
+ Data_Get_Struct(obj, OggVorbis_File, vf);
350
+ vi = ov_info(vf, NUM2INT(link));
351
+ return INT2FIX(vi->rate);
352
+ }
353
+
354
+ static VALUE
355
+ vf_comments(obj, link)
356
+ VALUE obj;
357
+ VALUE link;
358
+ {
359
+ vorbis_comment * vc = 0;
360
+ OggVorbis_File * vf = 0;
361
+ VALUE hash = rb_hash_new();
362
+ char ** ptr = 0;
363
+ VALUE key;
364
+ VALUE value;
365
+
366
+ Data_Get_Struct(obj, OggVorbis_File, vf);
367
+
368
+ ptr = ov_comment(vf, NUM2INT(link))->user_comments;
369
+
370
+ while (0 != *ptr)
371
+ {
372
+ char * s = *ptr;
373
+
374
+ char * equals_pos = strchr(s, '=');
375
+
376
+ if (0 != equals_pos)
377
+ {
378
+ /*
379
+ Vorbis comment keys are latin-1 (or ascii ?) and case-insensitive,
380
+ so let's do tolower() here. Why ? Well, otherwise people won't
381
+ be able to look up values in the hash.
382
+ */
383
+
384
+ int i = 0;
385
+
386
+ for (; i < equals_pos - s; i++)
387
+ s[i] = tolower(s[i]);
388
+
389
+ key = rb_str_new(s, equals_pos - s);
390
+ value = rb_str_new(equals_pos + 1, strlen(equals_pos + 1));
391
+
392
+ rb_hash_aset(hash, key, value);
393
+ }
394
+
395
+ ++ptr;
396
+ }
397
+
398
+ return hash;
399
+ }
400
+
401
+ static VALUE
402
+ vf_streams(obj)
403
+ VALUE obj;
404
+ {
405
+ OggVorbis_File * vf = 0;
406
+ Data_Get_Struct(obj, OggVorbis_File, vf);
407
+ return LONG2FIX(ov_streams(vf));
408
+ }
409
+
410
+ static VALUE
411
+ vf_bitrate(obj, link)
412
+ VALUE obj;
413
+ VALUE link;
414
+ {
415
+ OggVorbis_File * vf = 0;
416
+ Data_Get_Struct(obj, OggVorbis_File, vf);
417
+ return LONG2FIX(ov_bitrate(vf, NUM2INT(link)));
418
+ }
419
+
420
+ static VALUE
421
+ vf_bitrate_i(obj)
422
+ VALUE obj;
423
+ {
424
+ OggVorbis_File * vf = 0;
425
+ Data_Get_Struct(obj, OggVorbis_File, vf);
426
+
427
+ return LONG2FIX(ov_bitrate_instant(vf));
428
+ }
429
+
430
+ static VALUE
431
+ vf_seekable(obj)
432
+ VALUE obj;
433
+ {
434
+ OggVorbis_File * vf = 0;
435
+ Data_Get_Struct(obj, OggVorbis_File, vf);
436
+
437
+ return (1 == ov_seekable(vf)) ? Qtrue : Qfalse;
438
+ }
439
+
440
+ static VALUE
441
+ vf_serial_number(obj, link)
442
+ VALUE obj;
443
+ VALUE link;
444
+ {
445
+ OggVorbis_File * vf = 0;
446
+ Data_Get_Struct(obj, OggVorbis_File, vf);
447
+
448
+ return LONG2FIX(ov_serialnumber(vf, link));
449
+ }
450
+
451
+ void
452
+ Init_vorbisfile()
453
+ {
454
+ cOgg = rb_define_module("Ogg");
455
+
456
+ cVorbisFile = rb_define_class_under(cOgg, "VorbisFile", rb_cObject);
457
+
458
+ rb_define_singleton_method(cVorbisFile, "new", vf_s_new, -1);
459
+
460
+ rb_define_method(cVorbisFile, "initialize", vf_initialize, -1);
461
+ rb_define_method(cVorbisFile, "open", vf_open, 1);
462
+ rb_define_method(cVorbisFile, "read", vf_read, 5);
463
+ rb_define_method(cVorbisFile, "close", vf_close, 0);
464
+ rb_define_method(cVorbisFile, "raw_total", vf_raw_total, 1);
465
+ rb_define_method(cVorbisFile, "pcm_total", vf_pcm_total, 1);
466
+ rb_define_method(cVorbisFile, "time_total", vf_time_total, 1);
467
+ rb_define_method(cVorbisFile, "raw_seek", vf_raw_seek, 2);
468
+ rb_define_method(cVorbisFile, "pcm_seek", vf_pcm_seek, 2);
469
+ rb_define_method(cVorbisFile, "time_seek", vf_time_seek, 2);
470
+ rb_define_method(cVorbisFile, "raw_tell", vf_raw_tell, 1);
471
+ rb_define_method(cVorbisFile, "pcm_tell", vf_pcm_tell, 1);
472
+ rb_define_method(cVorbisFile, "time_tell", vf_time_tell, 1);
473
+ rb_define_method(cVorbisFile, "channels", vf_channels, 1);
474
+ rb_define_method(cVorbisFile, "sample_rate", vf_sample_rate, 1);
475
+ rb_define_method(cVorbisFile, "comments", vf_comments, 1);
476
+ rb_define_method(cVorbisFile, "streams", vf_streams, 0);
477
+ rb_define_method(cVorbisFile, "bitrate", vf_bitrate, 1);
478
+ rb_define_method(cVorbisFile, "bitrate_instant", vf_bitrate_i, 0);
479
+ rb_define_method(cVorbisFile, "seekable", vf_seekable, 0);
480
+ rb_define_method(cVorbisFile, "serial_number", vf_serial_number, 1);
481
+ }
482
+