catori 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -0
- data/bin/catori +9 -0
- data/changelog.txt +3 -0
- data/construir +3 -0
- data/crear_vista.sql +8 -0
- data/ext/audiofile/MANIFEST +8 -0
- data/ext/audiofile/README +11 -0
- data/ext/audiofile/audiofile.c +833 -0
- data/ext/audiofile/audiofile.rd +265 -0
- data/ext/audiofile/depend +0 -0
- data/ext/audiofile/extconf.rb +8 -0
- data/ext/audiofile/fail.rb +22 -0
- data/ext/audiofile/mkmf.log +34 -0
- data/ext/audiofile/test.rb +229 -0
- data/ext/flac/extconf.rb +5 -0
- data/ext/flac/flac.c +75 -0
- data/ext/flac/mkmf.log +12 -0
- data/ext/flac/test.rb +3 -0
- data/ext/mahoro-0.1/INSTALL +9 -0
- data/ext/mahoro-0.1/extconf.rb +7 -0
- data/ext/mahoro-0.1/mahoro.c +187 -0
- data/ext/mahoro-0.1/mkmf.log +24 -0
- data/ext/mahoro-0.1/test.rb +41 -0
- data/ext/mpc/extconf.rb +5 -0
- data/ext/mpc/id3tag.c +245 -0
- data/ext/mpc/id3tag.h +5 -0
- data/ext/mpc/mkmf.log +12 -0
- data/ext/mpc/mpc.c +56 -0
- data/ext/mpc/mpp.h +194 -0
- data/ext/mpc/mppdec.h +1171 -0
- data/ext/mpc/test.rb +3 -0
- data/ext/rmac/extconf.rb +7 -0
- data/ext/rmac/mkmf.log +22 -0
- data/ext/rmac/rmac.cpp +162 -0
- data/ext/vorbisfile/ChangeLog +11 -0
- data/ext/vorbisfile/README +33 -0
- data/ext/vorbisfile/configure +2 -0
- data/ext/vorbisfile/extconf.rb +9 -0
- data/ext/vorbisfile/mkmf.log +68 -0
- data/ext/vorbisfile/test.rb +78 -0
- data/ext/vorbisfile/vorbisfile.c +482 -0
- data/instalar.txt +19 -0
- data/install.rb +11 -0
- data/lib/audioinfo.rb +321 -0
- data/lib/catori.rb +131 -0
- data/lib/catori/Catalogador.rb +71 -0
- data/lib/catori/Db.rb +81 -0
- data/lib/catori/Gui.rb +52 -0
- data/lib/catori/Installer.rb +16 -0
- data/lib/catori/Query.rb +82 -0
- data/lib/catori/XML.rb +42 -0
- data/lib/catori/catori_gui.glade +340 -0
- data/lib/catori/catori_gui.glade.bak +340 -0
- data/lib/catori/catori_gui.gladep +8 -0
- data/lib/catori/catori_gui.gladep.bak +8 -0
- data/lib/catori/taglib.rb +227 -0
- data/lib/pixmaps/album.png +0 -0
- data/lib/pixmaps/artist.png +0 -0
- data/lib/pixmaps/cdr.png +0 -0
- data/lib/pixmaps/song.png +0 -0
- data/lib/taglib.rb +230 -0
- data/sql/catori_mysql.sql +68 -0
- data/sql/catori_pg.sql +65 -0
- data/tests/saw.ape +0 -0
- data/tests/saw.flac +0 -0
- data/tests/saw.mp3 +0 -0
- data/tests/saw.mpc +0 -0
- data/tests/saw.ogg +0 -0
- data/tests/saw.wav +0 -0
- data/tests/test_audioinfo.rb +43 -0
- metadata +217 -0
data/ext/mpc/test.rb
ADDED
data/ext/rmac/extconf.rb
ADDED
data/ext/rmac/mkmf.log
ADDED
@@ -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
|
+
|
data/ext/rmac/rmac.cpp
ADDED
@@ -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,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
|
+
|