bloopsaphone 0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ require 'mkmf'
2
+ require 'fileutils'
3
+
4
+ $CFLAGS << " -I../../c "
5
+
6
+ %w[../../c/notation.c ../../c/bloopsaphone.c ../../c/bloopsaphone.h].each do |fn|
7
+ abort "!! ERROR !!\n** #{fn} not found; type 'make ruby' in the top directory\n\n" \
8
+ unless File.exists? fn
9
+ FileUtils.cp(fn, ".")
10
+ end
11
+
12
+ have_library("portaudio")
13
+ create_makefile("bloops")
@@ -0,0 +1,282 @@
1
+ //
2
+ // rubyext.c
3
+ // the ruby binding to bloopsaphone
4
+ //
5
+ // (c) 2009 why the lucky stiff
6
+ //
7
+ #include <ruby.h>
8
+ #include "bloopsaphone.h"
9
+
10
+ static VALUE cBloops, cSound, cTrack;
11
+
12
+ #ifndef RSTRING_LEN
13
+ #define RSTRING_LEN(str) RSTRING(str)->len
14
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
15
+ #endif
16
+
17
+ //
18
+ // Main Bloops object
19
+ //
20
+ static void
21
+ rb_bloops_free(bloops *B)
22
+ {
23
+ bloops_destroy(B);
24
+ }
25
+
26
+ VALUE
27
+ rb_bloops_alloc(VALUE klass)
28
+ {
29
+ bloops *B = bloops_new();
30
+ return Data_Wrap_Struct(klass, NULL, rb_bloops_free, B);
31
+ }
32
+
33
+ VALUE
34
+ rb_bloops_clear(VALUE self)
35
+ {
36
+ bloops *B;
37
+ Data_Get_Struct(self, bloops, B);
38
+ bloops_clear(B);
39
+ return self;
40
+ }
41
+
42
+ VALUE
43
+ rb_bloops_play(VALUE self)
44
+ {
45
+ bloops *B;
46
+ Data_Get_Struct(self, bloops, B);
47
+ bloops_play(B);
48
+ return self;
49
+ }
50
+
51
+ VALUE
52
+ rb_bloops_is_stopped(VALUE self)
53
+ {
54
+ bloops *B;
55
+ Data_Get_Struct(self, bloops, B);
56
+ return bloops_is_done(B) ? Qtrue : Qfalse;
57
+ }
58
+
59
+ VALUE
60
+ rb_bloops_get_tempo(VALUE self)
61
+ {
62
+ bloops *B;
63
+ Data_Get_Struct(self, bloops, B);
64
+ return INT2NUM(B->tempo);
65
+ }
66
+
67
+ VALUE
68
+ rb_bloops_set_tempo(VALUE self, VALUE tempo)
69
+ {
70
+ bloops *B;
71
+ Data_Get_Struct(self, bloops, B);
72
+ bloops_tempo(B, NUM2INT(tempo));
73
+ return tempo;
74
+ }
75
+
76
+ //
77
+ // Instrument creation
78
+ //
79
+ static void
80
+ rb_bloops_sound_free(bloopsaphone *sound)
81
+ {
82
+ free(sound);
83
+ }
84
+
85
+ VALUE
86
+ rb_bloops_load(VALUE self, VALUE fname)
87
+ {
88
+ bloops *B;
89
+ bloopsaphone *P;
90
+ Data_Get_Struct(self, bloops, B);
91
+
92
+ StringValue(fname);
93
+ P = bloops_sound_file(B, RSTRING_PTR(fname));
94
+ if (P == NULL) return Qnil;
95
+ return Data_Wrap_Struct(cSound, NULL, rb_bloops_sound_free, P);
96
+ }
97
+
98
+ VALUE
99
+ rb_bloops_sound(VALUE self, VALUE type)
100
+ {
101
+ bloopsaphone *P = bloops_square();
102
+ P->type = (unsigned char)NUM2INT(type);
103
+ return Data_Wrap_Struct(cSound, NULL, rb_bloops_sound_free, P);
104
+ }
105
+
106
+ VALUE
107
+ rb_bloops_get_type(VALUE self)
108
+ {
109
+ bloopsaphone *P;
110
+ Data_Get_Struct(self, bloopsaphone, P);
111
+ return INT2NUM((int)P->type);
112
+ }
113
+
114
+ VALUE
115
+ rb_bloops_set_type(VALUE self, VALUE type)
116
+ {
117
+ bloopsaphone *P;
118
+ Data_Get_Struct(self, bloopsaphone, P);
119
+ P->type = (unsigned char)NUM2INT(type);
120
+ return type;
121
+ }
122
+
123
+ #define SOUND_ACCESSOR(name) \
124
+ VALUE rb_bloops_get_##name(VALUE self) { \
125
+ bloopsaphone *P; \
126
+ Data_Get_Struct(self, bloopsaphone, P); \
127
+ return rb_float_new(P->name); \
128
+ } \
129
+ VALUE rb_bloops_set_##name(VALUE self, VALUE f) { \
130
+ bloopsaphone *P; \
131
+ Data_Get_Struct(self, bloopsaphone, P); \
132
+ P->name = (float)NUM2DBL(f); \
133
+ return f; \
134
+ }
135
+
136
+ SOUND_ACCESSOR(arp);
137
+ SOUND_ACCESSOR(aspeed);
138
+ SOUND_ACCESSOR(attack);
139
+ SOUND_ACCESSOR(decay);
140
+ SOUND_ACCESSOR(dslide);
141
+ SOUND_ACCESSOR(freq);
142
+ SOUND_ACCESSOR(hpf);
143
+ SOUND_ACCESSOR(hsweep);
144
+ SOUND_ACCESSOR(limit);
145
+ SOUND_ACCESSOR(lpf);
146
+ SOUND_ACCESSOR(lsweep);
147
+ SOUND_ACCESSOR(phase);
148
+ SOUND_ACCESSOR(psweep);
149
+ SOUND_ACCESSOR(repeat);
150
+ SOUND_ACCESSOR(resonance);
151
+ SOUND_ACCESSOR(slide);
152
+ SOUND_ACCESSOR(square);
153
+ SOUND_ACCESSOR(sustain);
154
+ SOUND_ACCESSOR(sweep);
155
+ SOUND_ACCESSOR(punch);
156
+ SOUND_ACCESSOR(vibe);
157
+ SOUND_ACCESSOR(vspeed);
158
+ SOUND_ACCESSOR(vdelay);
159
+ SOUND_ACCESSOR(volume);
160
+
161
+ //
162
+ // Individual track object
163
+ //
164
+ static void
165
+ rb_bloops_track_free(bloopsatrack *track)
166
+ {
167
+ bloops_track_destroy(track);
168
+ }
169
+
170
+ VALUE
171
+ rb_bloops_tune(VALUE self, VALUE sound, VALUE notes)
172
+ {
173
+ int i;
174
+ bloops *B;
175
+ bloopsaphone *phone;
176
+ bloopsatrack *track;
177
+ Data_Get_Struct(self, bloops, B);
178
+ Data_Get_Struct(sound, bloopsaphone, phone);
179
+
180
+ StringValue(notes);
181
+ track = bloops_track(B, phone, RSTRING_PTR(notes), RSTRING_LEN(notes));
182
+
183
+ for (i = 0; i < BLOOPS_MAX_TRACKS; i++)
184
+ if (B->tracks[i] == NULL) {
185
+ bloops_track_at(B, track, i);
186
+ break;
187
+ }
188
+ return Data_Wrap_Struct(cTrack, NULL, rb_bloops_track_free, track);
189
+ }
190
+
191
+ VALUE
192
+ rb_bloops_track_str(VALUE self)
193
+ {
194
+ char *str;
195
+ VALUE obj;
196
+ bloopsatrack *track;
197
+ Data_Get_Struct(self, bloopsatrack, track);
198
+
199
+ str = bloops_track_str(track);
200
+ obj = rb_str_new2(str);
201
+ free(str);
202
+
203
+ return obj;
204
+ }
205
+
206
+ //
207
+ // Ruby extension startup
208
+ //
209
+ void
210
+ Init_bloops()
211
+ {
212
+ cBloops = rb_define_class("Bloops", rb_cObject);
213
+ rb_define_alloc_func(cBloops, rb_bloops_alloc);
214
+ rb_define_method(cBloops, "clear", rb_bloops_clear, 0);
215
+ rb_define_method(cBloops, "load", rb_bloops_load, 1);
216
+ rb_define_method(cBloops, "play", rb_bloops_play, 0);
217
+ rb_define_method(cBloops, "sound", rb_bloops_sound, 1);
218
+ rb_define_method(cBloops, "stopped?", rb_bloops_is_stopped, 0);
219
+ rb_define_method(cBloops, "tempo", rb_bloops_get_tempo, 0);
220
+ rb_define_method(cBloops, "tempo=", rb_bloops_set_tempo, 1);
221
+ rb_define_method(cBloops, "tune", rb_bloops_tune, 2);
222
+
223
+ rb_const_set(cBloops, rb_intern("SQUARE"), INT2NUM(BLOOPS_SQUARE));
224
+ rb_const_set(cBloops, rb_intern("SAWTOOTH"), INT2NUM(BLOOPS_SAWTOOTH));
225
+ rb_const_set(cBloops, rb_intern("SINE"), INT2NUM(BLOOPS_SINE));
226
+ rb_const_set(cBloops, rb_intern("NOISE"), INT2NUM(BLOOPS_NOISE));
227
+
228
+ cSound = rb_define_class_under(cBloops, "Sound", rb_cObject);
229
+ rb_define_method(cSound, "arp", rb_bloops_get_arp, 0);
230
+ rb_define_method(cSound, "arp=", rb_bloops_set_arp, 1);
231
+ rb_define_method(cSound, "aspeed", rb_bloops_get_aspeed, 0);
232
+ rb_define_method(cSound, "aspeed=", rb_bloops_set_aspeed, 1);
233
+ rb_define_method(cSound, "attack", rb_bloops_get_attack, 0);
234
+ rb_define_method(cSound, "attack=", rb_bloops_set_attack, 1);
235
+ rb_define_method(cSound, "decay", rb_bloops_get_decay, 0);
236
+ rb_define_method(cSound, "decay=", rb_bloops_set_decay, 1);
237
+ rb_define_method(cSound, "dslide", rb_bloops_get_dslide, 0);
238
+ rb_define_method(cSound, "dslide=", rb_bloops_set_dslide, 1);
239
+ rb_define_method(cSound, "freq", rb_bloops_get_freq, 0);
240
+ rb_define_method(cSound, "freq=", rb_bloops_set_freq, 1);
241
+ rb_define_method(cSound, "hpf", rb_bloops_get_hpf, 0);
242
+ rb_define_method(cSound, "hpf=", rb_bloops_set_hpf, 1);
243
+ rb_define_method(cSound, "hsweep", rb_bloops_get_hsweep, 0);
244
+ rb_define_method(cSound, "hsweep=", rb_bloops_set_hsweep, 1);
245
+ rb_define_method(cSound, "limit", rb_bloops_get_limit, 0);
246
+ rb_define_method(cSound, "limit=", rb_bloops_set_limit, 1);
247
+ rb_define_method(cSound, "lpf", rb_bloops_get_lpf, 0);
248
+ rb_define_method(cSound, "lpf=", rb_bloops_set_lpf, 1);
249
+ rb_define_method(cSound, "lsweep", rb_bloops_get_lsweep, 0);
250
+ rb_define_method(cSound, "lsweep=", rb_bloops_set_lsweep, 1);
251
+ rb_define_method(cSound, "phase", rb_bloops_get_phase, 0);
252
+ rb_define_method(cSound, "phase=", rb_bloops_set_phase, 1);
253
+ rb_define_method(cSound, "psweep", rb_bloops_get_psweep, 0);
254
+ rb_define_method(cSound, "psweep=", rb_bloops_set_psweep, 1);
255
+ rb_define_method(cSound, "punch", rb_bloops_get_punch, 0);
256
+ rb_define_method(cSound, "punch=", rb_bloops_set_punch, 1);
257
+ rb_define_method(cSound, "repeat", rb_bloops_get_repeat, 0);
258
+ rb_define_method(cSound, "repeat=", rb_bloops_set_repeat, 1);
259
+ rb_define_method(cSound, "resonance", rb_bloops_get_resonance, 0);
260
+ rb_define_method(cSound, "resonance=", rb_bloops_set_resonance, 1);
261
+ rb_define_method(cSound, "slide", rb_bloops_get_slide, 0);
262
+ rb_define_method(cSound, "slide=", rb_bloops_set_slide, 1);
263
+ rb_define_method(cSound, "square", rb_bloops_get_square, 0);
264
+ rb_define_method(cSound, "square=", rb_bloops_set_square, 1);
265
+ rb_define_method(cSound, "sweep", rb_bloops_get_sweep, 0);
266
+ rb_define_method(cSound, "sweep=", rb_bloops_set_sweep, 1);
267
+ rb_define_method(cSound, "sustain", rb_bloops_get_sustain, 0);
268
+ rb_define_method(cSound, "sustain=", rb_bloops_set_sustain, 1);
269
+ rb_define_method(cSound, "type", rb_bloops_get_type, 0);
270
+ rb_define_method(cSound, "type=", rb_bloops_set_type, 1);
271
+ rb_define_method(cSound, "vibe", rb_bloops_get_vibe, 0);
272
+ rb_define_method(cSound, "vibe=", rb_bloops_set_vibe, 1);
273
+ rb_define_method(cSound, "vspeed", rb_bloops_get_vspeed, 0);
274
+ rb_define_method(cSound, "vspeed=", rb_bloops_set_vspeed, 1);
275
+ rb_define_method(cSound, "vdelay", rb_bloops_get_vdelay, 0);
276
+ rb_define_method(cSound, "vdelay=", rb_bloops_set_vdelay, 1);
277
+ rb_define_method(cSound, "volume", rb_bloops_get_volume, 0);
278
+ rb_define_method(cSound, "volume=", rb_bloops_set_volume, 1);
279
+
280
+ cTrack = rb_define_class_under(cBloops, "Track", rb_cObject);
281
+ rb_define_method(cTrack, "to_s", rb_bloops_track_str, 0);
282
+ }
@@ -0,0 +1,26 @@
1
+ require './bloops'
2
+
3
+ # the song object
4
+ b = Bloops.new
5
+ b.tempo = 320
6
+
7
+ # an instrument
8
+ saw = b.sound Bloops::SAWTOOTH
9
+
10
+ # assign a track to the song
11
+ b.tune saw, "c5 c6 b4 b5 d5 d6 e5 e6"
12
+
13
+ # make it go
14
+ b.play
15
+ sleep 1 while !b.stopped?
16
+
17
+ # a percussion
18
+ beat = b.sound Bloops::NOISE
19
+ beat.repeat = 0.6
20
+
21
+ # assign a track to the song
22
+ b.tune beat, "4 4 b4 4 d5 4 e5 e6"
23
+
24
+ # make it go
25
+ b.play
26
+ sleep 1 while !b.stopped?
@@ -0,0 +1,25 @@
1
+ require './bloops'
2
+
3
+ b = Bloops.new
4
+
5
+ # ice #1
6
+ puts "** playing scale using ice.blu"
7
+ ice = b.load "../../sounds/ice.blu"
8
+ b.tune ice, "c c# d eb e f f# g ab a bb b + c"
9
+
10
+ b.play
11
+ sleep 1 while !b.stopped?
12
+
13
+ b.clear
14
+
15
+ # ice #2
16
+ puts "** same scale built from ruby"
17
+ ice2 = b.sound Bloops::SQUARE
18
+ ice2.punch = 0.441
19
+ ice2.sustain = 0.067
20
+ ice2.decay = 0.197
21
+ ice2.freq = 0.499
22
+ b.tune ice2, "c c# d eb e f f# g ab a bb b + c"
23
+
24
+ b.play
25
+ sleep 1 while !b.stopped?
@@ -0,0 +1,10 @@
1
+ type noise
2
+ punch 0.524
3
+ sustain 0.160
4
+ decay 0.367
5
+ freq 0.296
6
+ slide -0.373
7
+ vibe 0.665
8
+ vspeed 0.103
9
+ phase 0.141
10
+ psweep -0.005
@@ -0,0 +1,13 @@
1
+ type square
2
+ sustain 0.333
3
+ decay 0.380
4
+ freq 0.336
5
+ slide 0.292
6
+ square 0.289
7
+ sweep 0.020
8
+ vibe 0.002
9
+ lpf 0.220
10
+ lsweep 0.015
11
+ resonance 0.875
12
+ aspeed 0.035
13
+ repeat 0.551
@@ -0,0 +1,5 @@
1
+ type square
2
+ punch 0.441
3
+ sustain 0.067
4
+ decay 0.197
5
+ freq 0.499
@@ -0,0 +1,8 @@
1
+ type square
2
+ sustain 0.266
3
+ decay 0.187
4
+ freq 0.268
5
+ slide 0.179
6
+ square 0.326
7
+ vibe 0.227
8
+ vspeed 0.231
@@ -0,0 +1,19 @@
1
+ type square
2
+ volume 0.977
3
+ punch 0.190
4
+ sustain 0.165
5
+ slide 0.100
6
+ dslide 0.030
7
+ square 0.048
8
+ sweep -0.055
9
+ vibe 0.437
10
+ vspeed 0.310
11
+ lpf 0.355
12
+ resonance 0.185
13
+ hpf 0.205
14
+ hsweep 0.255
15
+ arp 0.677
16
+ aspeed 0.275
17
+ phase 0.200
18
+ psweep -0.565
19
+ repeat 0.500
@@ -0,0 +1,6 @@
1
+ type sawtooth
2
+ sustain 0.306
3
+ decay 0.477
4
+ freq 0.429
5
+ slide 0.217
6
+ repeat 0.677
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bloopsaphone
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.4"
5
+ platform: ruby
6
+ authors:
7
+ - why the lucky stiff
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-12 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: arcade sounds and chiptunes
17
+ email: why@ruby-lang.org
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/ruby/extconf.rb
22
+ extra_rdoc_files:
23
+ - README
24
+ - COPYING
25
+ files:
26
+ - COPYING
27
+ - README
28
+ - c/bloopsaphone.c
29
+ - c/bloopsaphone.h
30
+ - c/notation.c
31
+ - ext/ruby/extconf.rb
32
+ - ext/ruby/rubyext.c
33
+ - ext/ruby/test.rb
34
+ - ext/ruby/test_load.rb
35
+ - sounds/dart.blu
36
+ - sounds/error.blu
37
+ - sounds/ice.blu
38
+ - sounds/jump.blu
39
+ - sounds/pogo.blu
40
+ - sounds/stun.blu
41
+ has_rdoc: true
42
+ homepage: http://github.com/why/bloopsaphone
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.5
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: arcade sounds and chiptunes
69
+ test_files: []
70
+