gme 0.0.13-x86-linux → 0.1.0-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,25 +1,46 @@
1
- = GME: Game Music Emulator for Ruby
1
+ = GME: Game Music Emu for Ruby
2
2
 
3
- This gem allows the use of the gme library (http://code.google.com/p/game-music-emu)
4
- by Blargg (http://www.fly.net/~ant/libs/audio.html) in Ruby programs.
3
+ This gem allows the use of the {gme library}[http://code.google.com/p/game-music-emu]
4
+ by {Blargg}[http://www.fly.net/~ant/libs/audio.html] in Ruby programs.
5
5
 
6
- At the moment, it implements just the basic functionality, and it's not suitable for production.
6
+ Game Music Emu is a collection of video game music file emulators that support various formats and systems.
7
+
8
+ At the moment, this gem implements just the basic functionality, and it's not suitable for production.
9
+
10
+ == Installation
11
+ Using Rubygems:
12
+
13
+ gem install gme
7
14
 
8
15
  == Example usage:
9
16
 
10
- This gem only outputs raw pcm data, and doesn't include options for handling multi track files.
17
+ Note: This gem only outputs raw pcm data (16 bit samples, stereo).
11
18
 
19
+ require 'rubygems'
12
20
  require 'gme'
13
21
 
14
- song = GME::Emulator.open('/path/to/file.ext', options = {}) # opens a music file and sets up an GME::Emulator object
22
+ song = GME::Emulator.open('/path/to/file.ext', options = {}) # opens a music file and sets up a GME::Emulator object
15
23
  # configuration options:
16
24
  # :sample_rate - specifies the output sample rate
17
25
  # :buffer_length - specifies the internal buffer length to be used
18
26
 
19
- puts song.info # prints the information about the first track
27
+ file = File.new('output.pcm', 'w') # opens a file for writing
28
+
29
+ song.start_track(1) # starts the specified track (0 by default)
20
30
 
21
- song.play_to_file(file) # plays the first track of the song to a file
31
+ song.info # returns a hash with some information about the started track
22
32
 
23
- song.start_track(track_number) # starts the specified track (0 by default)
24
- song.get_samples # gets a number of samples
33
+ song.play(file, :samples => 1024) # writes the specified number of samples to a file
34
+
35
+ song.tell # returns the number of milliseconds played
36
+ # since the beginning of the track
37
+
38
+ song.set_fade(2000) # sets the number of milliseconds to start fading
39
+ # the track since the beginning of the track
40
+
41
+ song.play_silence(file, 2000) # writes the specified milliseconds of silence to a file
25
42
 
43
+ song.play_to_file(file) # completely plays the first track to a file
44
+
45
+ file.close # closes the ouput file
46
+ song.close # release the memory allocated for the emulator
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.13
1
+ 0.1.0
@@ -87,8 +87,8 @@ extout_prefix =
87
87
  target_prefix =
88
88
  LOCAL_LIBS =
89
89
  LIBS = $(LIBRUBYARG_SHARED) -lgme -lpthread -lrt -ldl -lcrypt -lm -lc
90
- SRCS = gme_funcs.c gme.c util.c
91
- OBJS = gme_funcs.o gme.o util.o
90
+ SRCS = gme.c util.c gme_funcs.c gme_helpers.c
91
+ OBJS = gme.o util.o gme_funcs.o gme_helpers.o
92
92
  TARGET = gme_ext
93
93
  DLLIB = $(TARGET).so
94
94
  EXTSTATIC =
data/ext/gme/build/gme.o CHANGED
Binary file
Binary file
Binary file
Binary file
data/ext/gme/build/util.o CHANGED
Binary file
data/ext/gme/gme.c CHANGED
@@ -1,6 +1,7 @@
1
1
  #include <ruby.h>
2
- #include "gme_funcs.h"
3
2
  #include "util.h"
3
+ #include "gme_helpers.h"
4
+ #include "gme_funcs.h"
4
5
 
5
6
  // classes and modules representations
6
7
  VALUE mGME;
@@ -22,13 +23,14 @@ void Init_gme_ext()
22
23
  cEmulator = rb_define_class_under(mGME, "Emulator", rb_cObject);
23
24
  rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("info")));
24
25
  rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("track_count")));
26
+ rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("sample_rate")));
25
27
 
26
28
  // for debugging
27
29
  rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("internal_buffer")));
28
30
  rb_funcall(cEmulator, rb_intern("attr_reader"), 1, ID2SYM(rb_intern("internal_buffer_length")));
29
31
  // ---
30
32
 
31
- /* rb_define_alloc_func(cEmulator, gme_alloc); */
33
+ // FIXME: open and play should have 1 mandatory parameter and the rest are optional (i.e.: -2 as parameter count)
32
34
  rb_define_singleton_method(cEmulator, "open", gme_ruby_open, -1);
33
35
  rb_define_method(cEmulator, "close", gme_ruby_close, 0);
34
36
  rb_define_method(cEmulator, "start_track", gme_ruby_start_track, -1);
@@ -38,4 +40,7 @@ void Init_gme_ext()
38
40
  rb_define_method(cEmulator, "tell", gme_ruby_tell, 0);
39
41
  rb_define_method(cEmulator, "track_ended?", gme_ruby_track_ended, 0);
40
42
  rb_define_method(cEmulator, "ignore_silence", gme_ruby_ignore_silence, 1);
43
+ rb_define_method(cEmulator, "set_fade", gme_ruby_set_fade, 1);
44
+ rb_define_method(cEmulator, "play", gme_ruby_play, -1);
45
+ rb_define_method(cEmulator, "play_silence", gme_ruby_play_silence, 2);
41
46
  }
data/ext/gme/gme_funcs.c CHANGED
@@ -1,4 +1,5 @@
1
1
  #include "gme_funcs.h"
2
+ #include "gme_helpers.h"
2
3
  #include "util.h"
3
4
 
4
5
  #include <rubyio.h>
@@ -8,19 +9,16 @@ extern VALUE eGenericException;
8
9
  extern VALUE eInvalidFile;
9
10
  extern VALUE eTrackNotStarted;
10
11
 
11
- void gme_ruby_emu_free(void* pointer);
12
-
13
12
  /*
14
- * Opens a new input file
15
- * Returns a new instance of GME::Emulator
13
+ * Opens a new input file.
14
+ * Returns a new instance of GME::Emulator.
15
+ * Accepts options in a hash (2nd argument).
16
16
  */
17
17
  VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
18
18
  {
19
- Music_Emu* emulator;
20
- int c_sample_rate;
21
- char* c_path;
22
- int track = 0; // uses track 0 for getting info (FIXME)
23
- gme_info_t* info;
19
+ Music_Emu* emulator;
20
+ int c_sample_rate;
21
+ char* c_path;
24
22
 
25
23
  // internal buffer
26
24
  short* buffer;
@@ -44,7 +42,7 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
44
42
  options = rb_hash_new();
45
43
  }
46
44
 
47
- // set sample rate
45
+ // set sample rate from options hash
48
46
  VALUE sample_rate = rb_hash_aref(options, ID2SYM(rb_intern("sample_rate")));
49
47
  if(!NIL_P(sample_rate)) {
50
48
  c_sample_rate = FIX2INT(sample_rate);
@@ -54,7 +52,7 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
54
52
  c_sample_rate = 44100;
55
53
  }
56
54
 
57
- // set buffer length
55
+ // set buffer length from options hash
58
56
  VALUE buffer_len = rb_hash_aref(options, ID2SYM(rb_intern("buffer_length")));
59
57
  if(!NIL_P(buffer_len)) {
60
58
  buffer_length = FIX2INT(buffer_len);
@@ -66,33 +64,18 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
66
64
 
67
65
  // opens the specified file
68
66
  handle_error(gme_open_file(c_path, &emulator, c_sample_rate), eInvalidFile);
69
- // and gets the info on the track
70
- handle_error(gme_track_info(emulator, &info, track), eGenericException);
71
67
 
72
68
  // creates a new instance of GME::Emulator, as a wrapper around Music_Emu
73
69
  VALUE new_instance = Data_Wrap_Struct(cEmulator, 0, gme_ruby_emu_free, emulator);
74
70
 
75
71
  // allocates memory for the internal buffer
76
- buffer = ALLOC_N(short, buffer_length);
77
- // and saves a reference for later use (hack?)
72
+ buffer = (short*) malloc(sizeof(short) * buffer_length);
73
+ // and saves a reference for later use (HACK?)
78
74
  rb_iv_set(new_instance, "@internal_buffer", LONG2NUM((long)buffer));
79
75
  rb_iv_set(new_instance, "@internal_buffer_length", INT2NUM(buffer_length));
80
76
 
81
- // Fills the info hash
82
- VALUE info_hash = rb_hash_new();
83
- rb_hash_aset(info_hash, ID2SYM(rb_intern("play_length")), INT2FIX(info->play_length));
84
- rb_hash_aset(info_hash, ID2SYM(rb_intern("length")), INT2FIX(info->length));
85
- rb_hash_aset(info_hash, ID2SYM(rb_intern("intro_length")), INT2FIX(info->intro_length));
86
- rb_hash_aset(info_hash, ID2SYM(rb_intern("loop_length")), INT2FIX(info->loop_length));
87
- rb_hash_aset(info_hash, ID2SYM(rb_intern("system")), rb_str_new2(info->system));
88
- rb_hash_aset(info_hash, ID2SYM(rb_intern("game")), rb_str_new2(info->game));
89
- rb_hash_aset(info_hash, ID2SYM(rb_intern("song")), rb_str_new2(info->song));
90
- rb_hash_aset(info_hash, ID2SYM(rb_intern("author")), rb_str_new2(info->author));
91
- rb_hash_aset(info_hash, ID2SYM(rb_intern("copyright")), rb_str_new2(info->copyright));
92
- rb_hash_aset(info_hash, ID2SYM(rb_intern("comment")), rb_str_new2(info->comment));
93
- rb_hash_aset(info_hash, ID2SYM(rb_intern("dumper")), rb_str_new2(info->dumper));
94
- rb_iv_set(new_instance, "@info", info_hash);
95
- gme_free_info(info);
77
+ // saves the sample rate value for future reference
78
+ rb_iv_set(new_instance, "@sample_rate", INT2FIX(c_sample_rate));
96
79
 
97
80
  // sets the track count
98
81
  int track_count = gme_track_count(emulator);
@@ -106,21 +89,37 @@ VALUE gme_ruby_open(int argc, VALUE* argv, VALUE self)
106
89
  }
107
90
 
108
91
  /*
109
- * is this function really needed?
92
+ * Releases all the resources allocated in Emulator#open.
93
+ * The object is unusable after this call.
94
+ * TODO: mark valid and invalid objects and raise exceptions if appropiate
95
+ * instead of simply failing or generating a segfault.
110
96
  */
111
97
  VALUE gme_ruby_close(VALUE self)
112
98
  {
113
- return Qnil;
99
+ Music_Emu* emulator;
100
+ short* c_buffer;
101
+
102
+ Data_Get_Struct(self, Music_Emu, emulator);
103
+
104
+ // recovers a pointer to the internal buffer
105
+ c_buffer = (short*) NUM2LONG(rb_iv_get(self, "@internal_buffer"));
106
+
107
+ // releases the memory
108
+ if(c_buffer != NULL) free(c_buffer);
109
+
110
+ return Qnil;
114
111
  }
115
112
 
116
113
  /*
117
- * starts a track
118
- * if not specified, uses track number 0
114
+ * Starts a track.
115
+ * If a track is not specified, uses track number 0.
116
+ * Returns the number of the track started.
119
117
  */
120
118
  VALUE gme_ruby_start_track(int argc, VALUE* argv, VALUE self)
121
119
  {
122
- Music_Emu* emulator;
123
- int c_track;
120
+ Music_Emu* emulator;
121
+ int c_track;
122
+ gme_info_t* info;
124
123
 
125
124
  Data_Get_Struct(self, Music_Emu, emulator);
126
125
 
@@ -133,6 +132,25 @@ VALUE gme_ruby_start_track(int argc, VALUE* argv, VALUE self)
133
132
  c_track = 0;
134
133
  }
135
134
 
135
+ // gets the info on the track
136
+ handle_error(gme_track_info(emulator, &info, c_track), eGenericException);
137
+
138
+ // Fills the info hash
139
+ VALUE info_hash = rb_hash_new();
140
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("play_length")), INT2FIX(info->play_length));
141
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("length")), INT2FIX(info->length));
142
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("intro_length")), INT2FIX(info->intro_length));
143
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("loop_length")), INT2FIX(info->loop_length));
144
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("system")), rb_str_new2(info->system));
145
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("game")), rb_str_new2(info->game));
146
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("song")), rb_str_new2(info->song));
147
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("author")), rb_str_new2(info->author));
148
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("copyright")), rb_str_new2(info->copyright));
149
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("comment")), rb_str_new2(info->comment));
150
+ rb_hash_aset(info_hash, ID2SYM(rb_intern("dumper")), rb_str_new2(info->dumper));
151
+ rb_iv_set(self, "@info", info_hash);
152
+ gme_free_info(info);
153
+
136
154
  // starts the track
137
155
  handle_error(gme_start_track(emulator, c_track), eGenericException);
138
156
 
@@ -153,14 +171,11 @@ VALUE gme_ruby_get_samples(VALUE self)
153
171
  short* c_buffer;
154
172
  int c_buffer_len;
155
173
 
156
- VALUE track_started = rb_iv_get(self, "@track_started");
157
- if(!RTEST(track_started)) rb_raise(eTrackNotStarted, "you must start a track first");
174
+ raise_if_track_has_not_started(self);
158
175
 
159
176
  Data_Get_Struct(self, Music_Emu, emulator);
160
177
 
161
- // recovers a pointer to the internal buffer
162
- c_buffer = (short*) NUM2LONG(rb_iv_get(self, "@internal_buffer"));
163
- c_buffer_len = NUM2INT(rb_iv_get(self, "@internal_buffer_length"));
178
+ get_internal_buffer(self, &c_buffer, &c_buffer_len);
164
179
 
165
180
  // plays the file, returning the specified number of samples
166
181
  handle_error(gme_play(emulator, c_buffer_len, c_buffer), eGenericException);
@@ -173,8 +188,8 @@ VALUE gme_ruby_get_samples(VALUE self)
173
188
  }
174
189
 
175
190
  /*
176
- * Plays the track 0 of the input file
177
- * and writes in the specified (ruby) output file
191
+ * Plays the track 0 of the input file,
192
+ * and writes in the specified (Ruby) output file.
178
193
  */
179
194
  VALUE gme_ruby_play_to_file(VALUE self, VALUE file)
180
195
  {
@@ -182,32 +197,22 @@ VALUE gme_ruby_play_to_file(VALUE self, VALUE file)
182
197
  short* buffer;
183
198
  FILE* stdio_file;
184
199
  Music_Emu* emulator;
185
- int track = 0; // plays track 0 (TODO?)
200
+
201
+ // plays track 0
202
+ // TODO: receive the track to play as an argument
203
+ int track = 0;
186
204
 
187
- // throws an exception if the file passed is not valid
188
- // FIXME: currently it *requires* an object of class File
189
- if(NIL_P(file) || TYPE(file) != T_FILE) {
190
- rb_raise(eGenericException, "the file is not valid.");
191
- }
205
+ raise_if_invalid_file(file);
206
+
207
+ stdio_file = get_stdio_pointer(file);
192
208
 
193
209
  // allocates memory for the buffer
194
210
  buffer = (short*) malloc(buffer_size * sizeof(short));
195
211
 
196
212
  Data_Get_Struct(self, Music_Emu, emulator);
197
213
 
198
- // TODO: fix for ruby-1.9 (fptr->stdio_file)
199
- stdio_file = RFILE(file)->fptr->f;
200
-
201
- // if the stdio pointer couldn't be accesed, exit the program
202
- if(stdio_file == NULL) {
203
- rb_fatal("Couldn't access stdio FILE pointer");
204
- }
205
-
206
- // starts track 0
207
- handle_error(gme_start_track(emulator, track), eGenericException);
208
-
209
- // track 0 has been started
210
- rb_iv_set(self, "@track_started", Qtrue);
214
+ // starts track
215
+ rb_funcall(self, rb_intern("start_track"), 1, INT2FIX(track));
211
216
 
212
217
  // gets the play length of the track from the info hash
213
218
  VALUE info_hash = rb_iv_get(self, "@info");
@@ -240,7 +245,7 @@ VALUE gme_ruby_track_started(VALUE self)
240
245
  }
241
246
 
242
247
  /*
243
- * Returns the number of milliseconds played since the start of the track
248
+ * Returns the number of milliseconds played since the start of the track.
244
249
  */
245
250
  VALUE gme_ruby_tell(VALUE self)
246
251
  {
@@ -255,7 +260,6 @@ VALUE gme_ruby_tell(VALUE self)
255
260
  return INT2FIX(milliseconds);
256
261
  }
257
262
 
258
-
259
263
  /*
260
264
  * Returns true if the track has ended
261
265
  * and false in other cases
@@ -264,9 +268,7 @@ VALUE gme_ruby_track_ended(VALUE self)
264
268
  {
265
269
  Music_Emu* emulator;
266
270
 
267
- // throws an exception if a track hasn't been started
268
- VALUE track_started = gme_ruby_track_started(self);
269
- if(!RTEST(track_started)) rb_raise(eTrackNotStarted, "you have to start a track first");
271
+ raise_if_track_has_not_started(self);
270
272
 
271
273
  Data_Get_Struct(self, Music_Emu, emulator);
272
274
 
@@ -278,8 +280,8 @@ VALUE gme_ruby_track_ended(VALUE self)
278
280
  }
279
281
 
280
282
  /*
281
- * sets whether or not to disable automatic end of track detection
282
- * and skipping at the beginning
283
+ * Sets whether or not to disable automatic end of track detection
284
+ * and skipping at the beginning.
283
285
  */
284
286
  VALUE gme_ruby_ignore_silence(VALUE self, VALUE ignore)
285
287
  {
@@ -296,9 +298,109 @@ VALUE gme_ruby_ignore_silence(VALUE self, VALUE ignore)
296
298
  }
297
299
 
298
300
  /*
299
- * free function to the GME::Emulator wrapper for Music_Emu
301
+ * Sets the time in milliseconds to start fading the track.
300
302
  */
301
- void gme_ruby_emu_free(void* pointer)
303
+ VALUE gme_ruby_set_fade(VALUE self, VALUE milliseconds)
302
304
  {
303
- if(pointer != NULL) gme_delete(pointer);
305
+ Music_Emu* emulator;
306
+
307
+ Data_Get_Struct(self, Music_Emu, emulator);
308
+
309
+ gme_set_fade(emulator, FIX2INT(milliseconds));
310
+
311
+ return Qnil;
312
+ }
313
+
314
+ /*
315
+ * Plays the started track to the specified file.
316
+ * Optionally, one can indicate the number of samples to be played
317
+ * (given that the buffer allocated previuosly is long enough).
318
+ */
319
+ VALUE gme_ruby_play(int argc, VALUE* argv, VALUE self)
320
+ {
321
+ Music_Emu* emulator;
322
+ int c_number_of_samples;
323
+ VALUE options; // options hash
324
+ VALUE file;
325
+ FILE* stdio_file;
326
+ short* c_buffer;
327
+ int c_buffer_len;
328
+
329
+ Data_Get_Struct(self, Music_Emu, emulator);
330
+
331
+ // file as the first argument
332
+ file = argv[0];
333
+
334
+ raise_if_invalid_file(file);
335
+
336
+ stdio_file = get_stdio_pointer(file);
337
+
338
+ raise_if_track_has_not_started(self);
339
+
340
+ // use the second argument, if present, as the options hash
341
+ VALUE temp;
342
+ if(argc >= 2){
343
+ temp = rb_check_convert_type(argv[1], T_HASH, "Hash", "to_hash");
344
+ if(!NIL_P(temp)) options = temp;
345
+ else options = rb_hash_new();
346
+ }
347
+ else {
348
+ options = rb_hash_new();
349
+ }
350
+
351
+ get_internal_buffer(self, &c_buffer, &c_buffer_len);
352
+
353
+ // determine the maximum number of samples to play given the buffer size
354
+ // (recall that buffer was allocated as an array of short)
355
+ int max_samples = c_buffer_len;
356
+
357
+ // sets the number of samples to play
358
+ VALUE samples = rb_hash_aref(options, ID2SYM(rb_intern("samples")));
359
+ if(!NIL_P(samples) && FIX2INT(samples) > 0 && FIX2INT(samples) <= max_samples) {
360
+ c_number_of_samples = FIX2INT(samples);
361
+ }
362
+ else {
363
+ // default, the maximum number of samples permitted by the allocated buffer
364
+ c_number_of_samples = max_samples;
365
+ }
366
+
367
+ // plays the file, getting the specified number of samples
368
+ handle_error(gme_play(emulator, c_number_of_samples, c_buffer), eGenericException);
369
+
370
+ // writes the samples to the file
371
+ write_samples(stdio_file, c_number_of_samples, c_buffer);
372
+ fflush(stdio_file);
373
+
374
+ // returns the number of samples
375
+ return INT2FIX(c_number_of_samples);
376
+ }
377
+
378
+ /*
379
+ * Inserts the specified milliseconds of silence in a file.
380
+ */
381
+ VALUE gme_ruby_play_silence(VALUE self, VALUE file, VALUE milliseconds)
382
+ {
383
+ Music_Emu* emulator;
384
+ FILE* stdio_file;
385
+ int samples_to_write;
386
+
387
+ Data_Get_Struct(self, Music_Emu, emulator);
388
+
389
+ raise_if_invalid_file(file);
390
+
391
+ stdio_file = get_stdio_pointer(file);
392
+
393
+ // gets the original sample rate specified for the emulator
394
+ int sample_rate = FIX2INT(rb_iv_get(self, "@sample_rate"));
395
+ samples_to_write = sample_rate * (FIX2INT(milliseconds) / 1000);
396
+
397
+ // writes a number of 0's as silence
398
+ // (4 in the next calculation because samples are 2 bytes and there are 2 channels)
399
+ int i;
400
+ for(i=0; i <(samples_to_write * 4); i++) {
401
+ fputc(0, stdio_file);
402
+ }
403
+ fflush(stdio_file);
404
+
405
+ return Qnil;
304
406
  }
data/ext/gme/gme_funcs.h CHANGED
@@ -13,5 +13,8 @@ VALUE gme_ruby_track_started(VALUE self);
13
13
  VALUE gme_ruby_tell(VALUE self);
14
14
  VALUE gme_ruby_track_ended(VALUE self);
15
15
  VALUE gme_ruby_ignore_silence(VALUE self, VALUE ignore);
16
+ VALUE gme_ruby_set_fade(VALUE self, VALUE milliseconds);
17
+ VALUE gme_ruby_play(int argc, VALUE* argv, VALUE self);
18
+ VALUE gme_ruby_play_silence(VALUE self, VALUE file, VALUE milliseconds);
16
19
 
17
20
  #endif
@@ -0,0 +1,59 @@
1
+ #include "gme_helpers.h"
2
+
3
+ /*
4
+ * free function to the GME::Emulator wrapper for Music_Emu
5
+ */
6
+ void gme_ruby_emu_free(void* pointer)
7
+ {
8
+ if(pointer != NULL) gme_delete(pointer);
9
+ }
10
+
11
+ /*
12
+ * Raises an exception if a track has not been started in the emulator.
13
+ */
14
+ void raise_if_track_has_not_started(VALUE emulator)
15
+ {
16
+ VALUE track_started = rb_iv_get(emulator, "@track_started");
17
+ if(!RTEST(track_started)) rb_raise(eTrackNotStarted, "you must start a track first");
18
+ }
19
+
20
+ /*
21
+ * Raises an exception the specified file is invalid.
22
+ * i.e. doesn't satisfy the required conditions.
23
+ */
24
+ void raise_if_invalid_file(VALUE file)
25
+ {
26
+ // FIXME: currently it *requires* an object of class File
27
+ if(NIL_P(file) || TYPE(file) != T_FILE) {
28
+ rb_raise(eGenericException, "the file is not valid.");
29
+ }
30
+
31
+ FILE* stdio_file = get_stdio_pointer(file);
32
+
33
+ // raises an exception if the stdio pointer couldn't be accesed
34
+ if(stdio_file == NULL) {
35
+ rb_raise(eGenericException, "couldn't access stdio FILE pointer of the specified file");
36
+ }
37
+ }
38
+
39
+ /*
40
+ * Recovers a pointer to the internal buffer of the emulator.
41
+ */
42
+ void get_internal_buffer(VALUE emulator, short** buffer, int* buffer_len)
43
+ {
44
+ *buffer = (short*) NUM2LONG(rb_iv_get(emulator, "@internal_buffer"));
45
+ *buffer_len = NUM2INT(rb_iv_get(emulator, "@internal_buffer_length"));
46
+ }
47
+
48
+ /*
49
+ * Gets the stdio pointer of the specified file.
50
+ */
51
+ FILE* get_stdio_pointer(VALUE file)
52
+ {
53
+ FILE* stdio_pointer = NULL;
54
+
55
+ // TODO: fix for ruby-1.9 (fptr->stdio_file)
56
+ stdio_pointer = RFILE(file)->fptr->f;
57
+
58
+ return stdio_pointer;
59
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef _GME_HELPERS_H
2
+ #define _GME_HELPERS_H
3
+
4
+ #include <ruby.h>
5
+ #include <rubyio.h>
6
+
7
+ extern VALUE eTrackNotStarted;
8
+ extern VALUE eGenericException;
9
+
10
+ void gme_ruby_emu_free(void* pointer);
11
+
12
+ void raise_if_track_has_not_started(VALUE emulator);
13
+ void raise_if_invalid_file(VALUE file);
14
+ void get_internal_buffer(VALUE emulator, short** buffer, int* buffer_len);
15
+ FILE* get_stdio_pointer(VALUE file);
16
+
17
+ #endif
data/lib/gme_ext.so CHANGED
Binary file
@@ -18,21 +18,8 @@ describe Emulator, "when first created" do
18
18
  @song.track_count.should == 1
19
19
  end
20
20
 
21
- it "should respond to the message 'info' and return a non-empty container" do
22
- @song.info.should_not be_empty
23
- end
24
-
25
- it "should correctly return the metadata of track 0 in a hash" do
26
- @song.info[:game].should == "Super Castlevania 4"
27
- @song.info[:song].should == "Stage Clear"
28
- @song.info[:length].should == 4000
29
- @song.info[:copyright].should == "1991 Konami"
30
- @song.info[:author].should == "Masanori Adachi, Taro Kudou"
31
- @song.info[:play_length].should == 4000
32
- @song.info[:comment].should == ""
33
- @song.info[:dumper].should == "Datschge"
34
- @song.info[:system].should == "Super Nintendo"
35
- @song.info[:loop_length].should == -1
21
+ it "should return nil when asked for info" do
22
+ @song.info.should be_nil
36
23
  end
37
24
 
38
25
  it "should indicate that no track has been started" do
@@ -77,7 +64,7 @@ describe Emulator, "when first created" do
77
64
  lambda { @song.play_to_file(@file) }.should_not raise_exception
78
65
  @song.close
79
66
  File.size("temp.out").should == 706560
80
- Digest::SHA1.hexdigest(File.read("temp.out")).should == "5a557efdb64cb71baa953b7129663b1503f4a7d9"
67
+ # TODO: check correctness of the generated file
81
68
  end
82
69
 
83
70
  after(:each) do
@@ -120,7 +107,26 @@ describe Emulator, "when first created" do
120
107
  @song.tell.should == 0
121
108
  end
122
109
 
123
- # TODO: get_samples, open with options, etc.
110
+ it "should not return nil when asked for the info" do
111
+ @song.info.should_not be_nil
112
+ end
124
113
 
114
+ it "should correctly return the metadata of the started track in a hash" do
115
+ @song.info[:game].should == "Super Castlevania 4"
116
+ @song.info[:song].should == "Stage Clear"
117
+ @song.info[:length].should == 4000
118
+ @song.info[:copyright].should == "1991 Konami"
119
+ @song.info[:author].should == "Masanori Adachi, Taro Kudou"
120
+ @song.info[:play_length].should == 4000
121
+ @song.info[:comment].should == ""
122
+ @song.info[:dumper].should == "Datschge"
123
+ @song.info[:system].should == "Super Nintendo"
124
+ @song.info[:loop_length].should == -1
125
+ end
126
+
127
+ # TODO: complete examples for the methods:
128
+ # get_samples, set_fade, play_silence, play, close, tell, ignore_silence
129
+ # TODO: add examples for the open method with options
130
+ # :sample_rate, :buffer_length
125
131
  end
126
132
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 13
9
- version: 0.0.13
9
+ version: 0.1.0
10
10
  platform: x86-linux
11
11
  authors:
12
12
  - "Carlos Beltr\xC3\xA1n-Recabarren"
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-30 00:00:00 -04:00
17
+ date: 2010-05-14 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -36,12 +36,15 @@ files:
36
36
  - ext/gme/build/gme.o
37
37
  - ext/gme/build/gme_ext.so
38
38
  - ext/gme/build/gme_funcs.o
39
+ - ext/gme/build/gme_helpers.o
39
40
  - ext/gme/build/mkmf.log
40
41
  - ext/gme/build/util.o
41
42
  - ext/gme/extconf.rb
42
43
  - ext/gme/gme.c
43
44
  - ext/gme/gme_funcs.c
44
45
  - ext/gme/gme_funcs.h
46
+ - ext/gme/gme_helpers.c
47
+ - ext/gme/gme_helpers.h
45
48
  - ext/gme/util.c
46
49
  - ext/gme/util.h
47
50
  - lib/gme.rb
@@ -79,5 +82,5 @@ signing_key:
79
82
  specification_version: 3
80
83
  summary: gme for Ruby
81
84
  test_files:
82
- - spec/emulator_spec.rb
83
85
  - spec/spec_helper.rb
86
+ - spec/emulator_spec.rb