gme 0.0.13-x86-linux → 0.1.0-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 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