gme 0.0.10-x86-linux → 0.0.12-x86-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +20 -1
- data/VERSION +1 -1
- data/ext/gme/gme.c +7 -1
- data/ext/gme/gme_funcs.c +46 -12
- data/ext/gme/gme_funcs.h +1 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
= GME: Game Music Emulator for Ruby
|
2
2
|
|
3
|
-
This gem allows the use of the gme library (http://code.google.com/p/game-music-emu
|
3
|
+
This gem allows the use of the gme library (http://code.google.com/p/game-music-emu)
|
4
4
|
by Blargg (http://www.fly.net/~ant/libs/audio.html) in Ruby programs.
|
5
5
|
|
6
6
|
At the moment, it implements just the basic functionality, and it's not suitable for production.
|
7
|
+
|
8
|
+
== Example usage:
|
9
|
+
|
10
|
+
This gem only outputs raw pcm data, and doesn't include options for handling multi track files.
|
11
|
+
|
12
|
+
require 'gme'
|
13
|
+
|
14
|
+
song = GME::Emulator.open('/path/to/file.ext', options = {}) # opens a music file and sets up an GME::Emulator object
|
15
|
+
# configuration options:
|
16
|
+
# :sample_rate - specifies the output sample rate
|
17
|
+
# :buffer_length - specifies the internal buffer length to be used
|
18
|
+
|
19
|
+
puts song.info # prints the information about the first track
|
20
|
+
|
21
|
+
song.play_to_file(file) # plays the first track of the song to a file
|
22
|
+
|
23
|
+
song.start_track(track_number) # starts the specified track (0 by default)
|
24
|
+
song.get_samples # gets a number of samples
|
25
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.12
|
data/ext/gme/gme.c
CHANGED
@@ -18,10 +18,16 @@ void Init_gme_ext()
|
|
18
18
|
cEmulator = rb_define_class_under(mGME, "Emulator", rb_cObject);
|
19
19
|
rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("info")));
|
20
20
|
rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("track_count")));
|
21
|
+
|
22
|
+
// for debugging
|
23
|
+
rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("internal_buffer")));
|
24
|
+
rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("internal_buffer_length")));
|
25
|
+
// ---
|
26
|
+
|
21
27
|
/* rb_define_alloc_func(cEmulator, gme_alloc); */
|
22
28
|
rb_define_singleton_method(cEmulator, "open", gme_ruby_open, -1);
|
23
29
|
rb_define_method(cEmulator, "close", gme_ruby_close, 0);
|
24
30
|
rb_define_method(cEmulator, "start_track", gme_ruby_start_track, -1);
|
25
|
-
rb_define_method(cEmulator, "get_samples", gme_ruby_get_samples,
|
31
|
+
rb_define_method(cEmulator, "get_samples", gme_ruby_get_samples, 0);
|
26
32
|
rb_define_method(cEmulator, "play_to_file", gme_ruby_play_to_file, 1);
|
27
33
|
}
|
data/ext/gme/gme_funcs.c
CHANGED
@@ -21,18 +21,48 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
|
|
21
21
|
int track = 0; // uses track 0 for getting info (FIXME)
|
22
22
|
gme_info_t* info;
|
23
23
|
|
24
|
+
// internal buffer
|
25
|
+
short* buffer;
|
26
|
+
int buffer_length;
|
27
|
+
|
28
|
+
// options hash
|
29
|
+
VALUE options;
|
30
|
+
|
24
31
|
// use the first (mandatory) argument, as path to file
|
25
32
|
VALUE string = StringValue(argv[0]);
|
26
33
|
c_path = RSTRING_PTR(string);
|
27
34
|
|
28
|
-
// use the second argument, if present, as
|
29
|
-
|
30
|
-
|
35
|
+
// use the second argument, if present, as the options hash
|
36
|
+
VALUE temp;
|
37
|
+
if(argc >= 2){
|
38
|
+
temp = rb_check_convert_type(argv[1], T_HASH, "Hash", "to_hash");
|
39
|
+
if(!NIL_P(temp)) options = temp;
|
40
|
+
else options = rb_hash_new();
|
31
41
|
}
|
32
42
|
else {
|
43
|
+
options = rb_hash_new();
|
44
|
+
}
|
45
|
+
|
46
|
+
// set sample rate
|
47
|
+
VALUE sample_rate = rb_hash_aref(options, ID2SYM(rb_intern("sample_rate")));
|
48
|
+
if(!NIL_P(sample_rate)) {
|
49
|
+
c_sample_rate = FIX2INT(sample_rate);
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
// default value
|
33
53
|
c_sample_rate = 44100;
|
34
54
|
}
|
35
55
|
|
56
|
+
// set buffer length
|
57
|
+
VALUE buffer_len = rb_hash_aref(options, ID2SYM(rb_intern("buffer_length")));
|
58
|
+
if(!NIL_P(buffer_len)) {
|
59
|
+
buffer_length = FIX2INT(buffer_len);
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
// default value
|
63
|
+
buffer_length = 2048;
|
64
|
+
}
|
65
|
+
|
36
66
|
// opens the specified file
|
37
67
|
handle_error(gme_open_file(c_path, &emulator, c_sample_rate), eInvalidFile);
|
38
68
|
// and gets the info on the track
|
@@ -41,6 +71,12 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
|
|
41
71
|
// creates a new instance of GME::Emulator, as a wrapper around Music_Emu
|
42
72
|
VALUE new_instance = Data_Wrap_Struct(cEmulator, 0, gme_ruby_emu_free, emulator);
|
43
73
|
|
74
|
+
// allocates memory for the internal buffer
|
75
|
+
buffer = ALLOC_N(short, buffer_length);
|
76
|
+
// and saves a reference for later use (hack?)
|
77
|
+
rb_iv_set(new_instance, "@internal_buffer", LONG2NUM((long)buffer));
|
78
|
+
rb_iv_set(new_instance, "@internal_buffer_length", INT2NUM(buffer_length));
|
79
|
+
|
44
80
|
// Fills the info hash
|
45
81
|
VALUE info_hash = rb_hash_new();
|
46
82
|
rb_hash_aset(info_hash, ID2SYM(rb_intern("play_length")), INT2FIX(info->play_length));
|
@@ -105,26 +141,24 @@ VALUE gme_ruby_start_track(int argc, VALUE* argv, VALUE self)
|
|
105
141
|
* FIXME: This function allocates a buffer each time it is called.
|
106
142
|
* Maybe we should use a one-time allocated buffer.
|
107
143
|
*/
|
108
|
-
VALUE gme_ruby_get_samples(VALUE self
|
144
|
+
VALUE gme_ruby_get_samples(VALUE self)
|
109
145
|
{
|
110
|
-
int buffer_size = FIX2INT(samples); // buffer size equal to number of samples
|
111
146
|
Music_Emu* emulator;
|
112
147
|
int c_samples;
|
113
148
|
short* c_buffer;
|
149
|
+
int c_buffer_len;
|
114
150
|
|
115
151
|
Data_Get_Struct(self, Music_Emu, emulator);
|
116
152
|
|
117
|
-
//
|
118
|
-
c_buffer = (short*)
|
153
|
+
// recovers a pointer to the internal buffer
|
154
|
+
c_buffer = (short*) NUM2LONG(rb_iv_get(self, "@internal_buffer"));
|
155
|
+
c_buffer_len = NUM2INT(rb_iv_get(self, "@internal_buffer_length"));
|
119
156
|
|
120
157
|
// plays the file, returning the specified number of samples
|
121
|
-
handle_error(gme_play(emulator,
|
158
|
+
handle_error(gme_play(emulator, c_buffer_len, c_buffer), eGenericException);
|
122
159
|
|
123
160
|
// creates a ruby string, containing the buffer content (generated samples)
|
124
|
-
VALUE ruby_string = rb_str_new((const char*)c_buffer,
|
125
|
-
|
126
|
-
// releases the allocated memory
|
127
|
-
free(c_buffer);
|
161
|
+
VALUE ruby_string = rb_str_new((const char*)c_buffer, c_buffer_len * sizeof(short));
|
128
162
|
|
129
163
|
// returns the played samples
|
130
164
|
return ruby_string;
|
data/ext/gme/gme_funcs.h
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self);
|
8
8
|
VALUE gme_ruby_close(VALUE self);
|
9
9
|
VALUE gme_ruby_start_track(int argc, VALUE* argv, VALUE self);
|
10
|
-
VALUE gme_ruby_get_samples(VALUE self
|
10
|
+
VALUE gme_ruby_get_samples(VALUE self);
|
11
11
|
VALUE gme_ruby_play_to_file(VALUE self, VALUE file);
|
12
12
|
|
13
13
|
#endif
|