bloopsaphone 0.4

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.
@@ -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
+