bloops 0.5

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,332 @@
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
+ static bloopsaphone *Pplain;
12
+
13
+ #ifndef RSTRING_LEN
14
+ #define RSTRING_LEN(str) RSTRING(str)->len
15
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
16
+ #endif
17
+
18
+ //
19
+ // Main Bloops object
20
+ //
21
+ static void
22
+ rb_bloops_free(bloops *B)
23
+ {
24
+ bloops_destroy(B);
25
+ }
26
+
27
+ VALUE
28
+ rb_bloops_alloc(VALUE klass)
29
+ {
30
+ bloops *B = bloops_new();
31
+ return Data_Wrap_Struct(klass, NULL, rb_bloops_free, B);
32
+ }
33
+
34
+ VALUE
35
+ rb_bloops_clear(VALUE self)
36
+ {
37
+ bloops *B;
38
+ Data_Get_Struct(self, bloops, B);
39
+ bloops_clear(B);
40
+ return self;
41
+ }
42
+
43
+ VALUE
44
+ rb_bloops_play(VALUE self)
45
+ {
46
+ bloops *B;
47
+ Data_Get_Struct(self, bloops, B);
48
+ bloops_play(B);
49
+ return self;
50
+ }
51
+
52
+ VALUE
53
+ rb_bloops_is_stopped(VALUE self)
54
+ {
55
+ bloops *B;
56
+ Data_Get_Struct(self, bloops, B);
57
+ return bloops_is_done(B) ? Qtrue : Qfalse;
58
+ }
59
+
60
+ VALUE
61
+ rb_bloops_get_tempo(VALUE self)
62
+ {
63
+ bloops *B;
64
+ Data_Get_Struct(self, bloops, B);
65
+ return INT2NUM(B->tempo);
66
+ }
67
+
68
+ VALUE
69
+ rb_bloops_set_tempo(VALUE self, VALUE tempo)
70
+ {
71
+ bloops *B;
72
+ Data_Get_Struct(self, bloops, B);
73
+ bloops_tempo(B, NUM2INT(tempo));
74
+ return tempo;
75
+ }
76
+
77
+ //
78
+ // Instrument creation
79
+ //
80
+ static void
81
+ rb_bloops_sound_free(bloopsaphone *sound)
82
+ {
83
+ bloops_sound_destroy(sound);
84
+ }
85
+
86
+ VALUE
87
+ rb_bloops_load(VALUE self, VALUE fname)
88
+ {
89
+ bloops *B;
90
+ bloopsaphone *P;
91
+ Data_Get_Struct(self, bloops, B);
92
+
93
+ StringValue(fname);
94
+ P = bloops_sound_file(B, RSTRING_PTR(fname));
95
+ if (P == NULL) return Qnil;
96
+ return Data_Wrap_Struct(cSound, NULL, rb_bloops_sound_free, P);
97
+ }
98
+
99
+ VALUE
100
+ rb_bloops_sound(VALUE self, VALUE type)
101
+ {
102
+ bloopsaphone *P = bloops_square();
103
+ P->params.type = (unsigned char)NUM2INT(type);
104
+ return Data_Wrap_Struct(cSound, NULL, rb_bloops_sound_free, P);
105
+ }
106
+
107
+ VALUE
108
+ rb_bloops_sound_copy(VALUE self, VALUE other)
109
+ {
110
+ bloopsaphone *P;
111
+ bloopsaphone *O;
112
+ Data_Get_Struct(self, bloopsaphone, P);
113
+ Data_Get_Struct(other, bloopsaphone, O);
114
+ bloops_sound_copy(P, O);
115
+ return Qnil;
116
+ }
117
+
118
+ VALUE
119
+ rb_bloops_sound_str(VALUE self)
120
+ {
121
+ bloopsaphone *P;
122
+ Data_Get_Struct(self, bloopsaphone, P);
123
+ return rb_str_new2(bloops_sound_str(P));
124
+ }
125
+
126
+ VALUE
127
+ rb_bloops_reset(VALUE self)
128
+ {
129
+ bloopsaphone *P;
130
+ Data_Get_Struct(self, bloopsaphone, P);
131
+ bloops_sound_copy(P, Pplain);
132
+ return self;
133
+ }
134
+
135
+ VALUE
136
+ rb_bloops_test(VALUE self)
137
+ {
138
+ bloops *B;
139
+ bloopsatrack *T;
140
+ bloopsaphone *P;
141
+
142
+ Data_Get_Struct(self, bloopsaphone, P);
143
+
144
+ B = bloops_new();
145
+ bloops_tempo(B, 120);
146
+ T = bloops_track2(B, P, "C");
147
+ T->notes[0].tone = 'n';
148
+ memcpy(&T->params, &P->params, sizeof(bloopsaparams));
149
+ bloops_play(B);
150
+ bloops_track_destroy(T);
151
+ bloops_destroy(B);
152
+
153
+ return self;
154
+ }
155
+
156
+ VALUE
157
+ rb_bloops_get_type(VALUE self)
158
+ {
159
+ bloopsaphone *P;
160
+ Data_Get_Struct(self, bloopsaphone, P);
161
+ return INT2NUM((int)P->params.type);
162
+ }
163
+
164
+ VALUE
165
+ rb_bloops_set_type(VALUE self, VALUE type)
166
+ {
167
+ bloopsaphone *P;
168
+ Data_Get_Struct(self, bloopsaphone, P);
169
+ P->params.type = (unsigned char)NUM2INT(type);
170
+ return type;
171
+ }
172
+
173
+ #define SOUND_ACCESSOR(name) \
174
+ VALUE rb_bloops_get_##name(VALUE self) { \
175
+ bloopsaphone *P; \
176
+ Data_Get_Struct(self, bloopsaphone, P); \
177
+ return rb_float_new(P->params.name); \
178
+ } \
179
+ VALUE rb_bloops_set_##name(VALUE self, VALUE f) { \
180
+ bloopsaphone *P; \
181
+ Data_Get_Struct(self, bloopsaphone, P); \
182
+ P->params.name = (float)NUM2DBL(f); \
183
+ return f; \
184
+ }
185
+
186
+ SOUND_ACCESSOR(arp);
187
+ SOUND_ACCESSOR(aspeed);
188
+ SOUND_ACCESSOR(attack);
189
+ SOUND_ACCESSOR(decay);
190
+ SOUND_ACCESSOR(dslide);
191
+ SOUND_ACCESSOR(freq);
192
+ SOUND_ACCESSOR(hpf);
193
+ SOUND_ACCESSOR(hsweep);
194
+ SOUND_ACCESSOR(limit);
195
+ SOUND_ACCESSOR(lpf);
196
+ SOUND_ACCESSOR(lsweep);
197
+ SOUND_ACCESSOR(phase);
198
+ SOUND_ACCESSOR(psweep);
199
+ SOUND_ACCESSOR(repeat);
200
+ SOUND_ACCESSOR(resonance);
201
+ SOUND_ACCESSOR(slide);
202
+ SOUND_ACCESSOR(square);
203
+ SOUND_ACCESSOR(sustain);
204
+ SOUND_ACCESSOR(sweep);
205
+ SOUND_ACCESSOR(punch);
206
+ SOUND_ACCESSOR(vibe);
207
+ SOUND_ACCESSOR(vspeed);
208
+ SOUND_ACCESSOR(vdelay);
209
+ SOUND_ACCESSOR(volume);
210
+
211
+ //
212
+ // Individual track object
213
+ //
214
+ static void
215
+ rb_bloops_track_free(bloopsatrack *track)
216
+ {
217
+ bloops_track_destroy(track);
218
+ }
219
+
220
+ VALUE
221
+ rb_bloops_tune(VALUE self, VALUE sound, VALUE notes)
222
+ {
223
+ bloops *B;
224
+ bloopsaphone *phone;
225
+ bloopsatrack *track;
226
+ Data_Get_Struct(self, bloops, B);
227
+ Data_Get_Struct(sound, bloopsaphone, phone);
228
+
229
+ StringValue(notes);
230
+ track = bloops_track(B, phone, RSTRING_PTR(notes), RSTRING_LEN(notes));
231
+ return Data_Wrap_Struct(cTrack, NULL, rb_bloops_track_free, track);
232
+ }
233
+
234
+ VALUE
235
+ rb_bloops_track_str(VALUE self)
236
+ {
237
+ char *str;
238
+ VALUE obj;
239
+ bloopsatrack *track;
240
+ Data_Get_Struct(self, bloopsatrack, track);
241
+
242
+ str = bloops_track_str(track);
243
+ obj = rb_str_new2(str);
244
+ free(str);
245
+
246
+ return obj;
247
+ }
248
+
249
+ //
250
+ // Ruby extension startup
251
+ //
252
+ void
253
+ Init_bloops()
254
+ {
255
+ Pplain = bloops_square();
256
+
257
+ cBloops = rb_define_class("Bloops", rb_cObject);
258
+ rb_define_alloc_func(cBloops, rb_bloops_alloc);
259
+ rb_define_method(cBloops, "clear", rb_bloops_clear, 0);
260
+ rb_define_method(cBloops, "load", rb_bloops_load, 1);
261
+ rb_define_method(cBloops, "play", rb_bloops_play, 0);
262
+ rb_define_method(cBloops, "sound", rb_bloops_sound, 1);
263
+ rb_define_singleton_method(cBloops, "sound", rb_bloops_sound, 1);
264
+ rb_define_method(cBloops, "stopped?", rb_bloops_is_stopped, 0);
265
+ rb_define_method(cBloops, "tempo", rb_bloops_get_tempo, 0);
266
+ rb_define_method(cBloops, "tempo=", rb_bloops_set_tempo, 1);
267
+ rb_define_method(cBloops, "tune", rb_bloops_tune, 2);
268
+
269
+ rb_const_set(cBloops, rb_intern("SQUARE"), INT2NUM(BLOOPS_SQUARE));
270
+ rb_const_set(cBloops, rb_intern("SAWTOOTH"), INT2NUM(BLOOPS_SAWTOOTH));
271
+ rb_const_set(cBloops, rb_intern("SINE"), INT2NUM(BLOOPS_SINE));
272
+ rb_const_set(cBloops, rb_intern("NOISE"), INT2NUM(BLOOPS_NOISE));
273
+
274
+ cSound = rb_define_class_under(cBloops, "Sound", rb_cObject);
275
+ rb_define_method(cSound, "initialize_copy", rb_bloops_sound_copy, 1);
276
+ rb_define_method(cSound, "to_s", rb_bloops_sound_str, 0);
277
+ rb_define_method(cSound, "reset", rb_bloops_reset, 0);
278
+ rb_define_method(cSound, "test", rb_bloops_test, 0);
279
+ rb_define_method(cSound, "arp", rb_bloops_get_arp, 0);
280
+ rb_define_method(cSound, "arp=", rb_bloops_set_arp, 1);
281
+ rb_define_method(cSound, "aspeed", rb_bloops_get_aspeed, 0);
282
+ rb_define_method(cSound, "aspeed=", rb_bloops_set_aspeed, 1);
283
+ rb_define_method(cSound, "attack", rb_bloops_get_attack, 0);
284
+ rb_define_method(cSound, "attack=", rb_bloops_set_attack, 1);
285
+ rb_define_method(cSound, "decay", rb_bloops_get_decay, 0);
286
+ rb_define_method(cSound, "decay=", rb_bloops_set_decay, 1);
287
+ rb_define_method(cSound, "dslide", rb_bloops_get_dslide, 0);
288
+ rb_define_method(cSound, "dslide=", rb_bloops_set_dslide, 1);
289
+ rb_define_method(cSound, "freq", rb_bloops_get_freq, 0);
290
+ rb_define_method(cSound, "freq=", rb_bloops_set_freq, 1);
291
+ rb_define_method(cSound, "hpf", rb_bloops_get_hpf, 0);
292
+ rb_define_method(cSound, "hpf=", rb_bloops_set_hpf, 1);
293
+ rb_define_method(cSound, "hsweep", rb_bloops_get_hsweep, 0);
294
+ rb_define_method(cSound, "hsweep=", rb_bloops_set_hsweep, 1);
295
+ rb_define_method(cSound, "limit", rb_bloops_get_limit, 0);
296
+ rb_define_method(cSound, "limit=", rb_bloops_set_limit, 1);
297
+ rb_define_method(cSound, "lpf", rb_bloops_get_lpf, 0);
298
+ rb_define_method(cSound, "lpf=", rb_bloops_set_lpf, 1);
299
+ rb_define_method(cSound, "lsweep", rb_bloops_get_lsweep, 0);
300
+ rb_define_method(cSound, "lsweep=", rb_bloops_set_lsweep, 1);
301
+ rb_define_method(cSound, "phase", rb_bloops_get_phase, 0);
302
+ rb_define_method(cSound, "phase=", rb_bloops_set_phase, 1);
303
+ rb_define_method(cSound, "psweep", rb_bloops_get_psweep, 0);
304
+ rb_define_method(cSound, "psweep=", rb_bloops_set_psweep, 1);
305
+ rb_define_method(cSound, "punch", rb_bloops_get_punch, 0);
306
+ rb_define_method(cSound, "punch=", rb_bloops_set_punch, 1);
307
+ rb_define_method(cSound, "repeat", rb_bloops_get_repeat, 0);
308
+ rb_define_method(cSound, "repeat=", rb_bloops_set_repeat, 1);
309
+ rb_define_method(cSound, "resonance", rb_bloops_get_resonance, 0);
310
+ rb_define_method(cSound, "resonance=", rb_bloops_set_resonance, 1);
311
+ rb_define_method(cSound, "slide", rb_bloops_get_slide, 0);
312
+ rb_define_method(cSound, "slide=", rb_bloops_set_slide, 1);
313
+ rb_define_method(cSound, "square", rb_bloops_get_square, 0);
314
+ rb_define_method(cSound, "square=", rb_bloops_set_square, 1);
315
+ rb_define_method(cSound, "sweep", rb_bloops_get_sweep, 0);
316
+ rb_define_method(cSound, "sweep=", rb_bloops_set_sweep, 1);
317
+ rb_define_method(cSound, "sustain", rb_bloops_get_sustain, 0);
318
+ rb_define_method(cSound, "sustain=", rb_bloops_set_sustain, 1);
319
+ rb_define_method(cSound, "type", rb_bloops_get_type, 0);
320
+ rb_define_method(cSound, "type=", rb_bloops_set_type, 1);
321
+ rb_define_method(cSound, "vibe", rb_bloops_get_vibe, 0);
322
+ rb_define_method(cSound, "vibe=", rb_bloops_set_vibe, 1);
323
+ rb_define_method(cSound, "vspeed", rb_bloops_get_vspeed, 0);
324
+ rb_define_method(cSound, "vspeed=", rb_bloops_set_vspeed, 1);
325
+ rb_define_method(cSound, "vdelay", rb_bloops_get_vdelay, 0);
326
+ rb_define_method(cSound, "vdelay=", rb_bloops_set_vdelay, 1);
327
+ rb_define_method(cSound, "volume", rb_bloops_get_volume, 0);
328
+ rb_define_method(cSound, "volume=", rb_bloops_set_volume, 1);
329
+
330
+ cTrack = rb_define_class_under(cBloops, "Track", rb_cObject);
331
+ rb_define_method(cTrack, "to_s", rb_bloops_track_str, 0);
332
+ }
data/ext/ruby/test.rb ADDED
@@ -0,0 +1,41 @@
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
+ saw.test
10
+
11
+ # assign a track to the song
12
+ b.tune saw, "c5 c6 b4 b5 d5 d6 e5 e6"
13
+
14
+ # make it go
15
+ b.play
16
+ sleep 1 while !b.stopped?
17
+
18
+ # a percussion
19
+ beat = b.sound Bloops::NOISE
20
+ beat.repeat = 0.6
21
+ beat2 = b.sound Bloops::NOISE
22
+ beat2.repeat = 0.2
23
+ beat3 = b.sound Bloops::SQUARE
24
+ beat3.sustain = 0.25
25
+ beat3.decay = 0.2
26
+ beat3.slide = 0.2
27
+ beat3.square = 0.3
28
+ beat3.vibe = 0.25
29
+ beat3.vspeed = 0.25
30
+
31
+ # assign a track to the song
32
+ b.tune beat, "4 4 4 b4 4 d5 4 e5"
33
+ b.tune beat2, "c2 4 c2 4 c2 4 c2 4"
34
+ b.tune beat3, "4 4 4 4 4 c2 c5 4"
35
+
36
+ # make it go
37
+ loop do
38
+ b.play
39
+ saw.test
40
+ sleep 0.02 while !b.stopped?
41
+ end
@@ -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,210 @@
1
+ #
2
+ # -)= Cheeky Drat (=-
3
+ # composed by freQvibez
4
+ # [within TextMate]
5
+ # exclusively for _why's BloopSaphone
6
+ #
7
+ # from Farbrausch with ♥
8
+ #
9
+
10
+ require './bloops'
11
+
12
+ b = Bloops.new
13
+ b.tempo = 172
14
+
15
+ bass = b.sound Bloops::SQUARE
16
+ bass.volume = 0.4
17
+ bass.sustain = 0.1
18
+ bass.attack = 0.1
19
+ bass.decay = 0.3
20
+
21
+ base = b.sound Bloops::SQUARE
22
+ base.volume = 0.35
23
+ base.punch = 0.3
24
+ base.sustain = 0.1
25
+ base.decay = 0.3
26
+ base.phase = 0.2
27
+ base.lpf = 0.115
28
+ base.resonance = 0.55
29
+ base.slide = -0.4
30
+
31
+ snare = b.sound Bloops::NOISE
32
+ snare.attack = 0.075
33
+ snare.sustain = 0.01
34
+ snare.decay = 0.33
35
+ snare.hpf = 0.55
36
+ snare.resonance = 0.44
37
+ snare.dslide = -0.452
38
+
39
+ chord = b.sound Bloops::SQUARE
40
+ chord.volume = 0.275
41
+ chord.attack = 0.05
42
+ chord.sustain = 0.6
43
+ chord.decay = 0.9
44
+ chord.phase = 0.35
45
+ chord.psweep = -0.25
46
+ chord.vibe = 0.0455
47
+ chord.vspeed = 0.255
48
+
49
+ lead = b.sound Bloops::SINE
50
+ lead.volume = 0.45
51
+ lead.attack = 0.3
52
+ lead.sustain = 0.15
53
+ lead.decay = 0.8
54
+ lead.vibe = 0.035
55
+ lead.vspeed = 0.345
56
+ lead.vdelay = -0.5
57
+ lead.hpf = 0.2
58
+ lead.hsweep = -0.05
59
+ lead.resonance = 0.55
60
+ lead.phase = 0.4
61
+ lead.psweep = -0.05
62
+
63
+ b.tune bass, %q^
64
+ 8 4a1 8a 8a 4a 4a 4c2 9c 7c 4c 8e
65
+ 8 4g2 8g 8 4g 4g 4d2 8 8c3 4b2 8e
66
+ 8 4d2 8c 8c 4c 4 4a2 9a 7a 4a 8a
67
+ 8 4g2 8g 8 4g 4d 4d2 9e3 7c2 8 4b1
68
+
69
+ 8 4a2 8a 8d 4 4d 4a1 8a 8a 4d 8d
70
+ 8 4g2 8g 8 4g 4g 4c2 8c 8c2 4g 8c
71
+ 8 4d2 8d 8d 4d 4d 4a1 8a 8a 4a 8a
72
+ 8 4g2 8g 8 4g 4g 4c2 8c 8c 4c 8b1
73
+
74
+ 8 4a1 8a 8a 4a 4a 4c2 9c 7c 4c 8e
75
+ 8 4g2 8g 8 4g 4g 4d2 8 8c3 4b2 8e
76
+ 8 4d2 8c 8c 4c 4 4a2 9a 7a 4a 8a
77
+ 8 4g2 8g 8 4g 4d 4d2 9e3 7c2 8 4b1
78
+
79
+ 8 4a2 8a 8d 4 4d 4a1 8a 8a 4d 8d
80
+ 8 4g2 8g 8 4g 4g 4c2 8c 8c2 4g 8c
81
+ 8 4d2 8d 8d 4d 4d 4a1 8a 8a 4a 8a
82
+ 8 4g2 8g 8 4g 4g 4c2 8c 8c 4c 8b1
83
+ ^
84
+
85
+ b.tune base, %q^
86
+ 4a2 4 8a 8a 4 4a 4 8a 8a 4
87
+ 4a 4 8a 8a 4 4a 4 4a 8 8a
88
+ 4a 4 8a 8a 4 4a 4 8a 8a 4
89
+ 4a 4 8a 4 8a 4a 4 8a 4 8a
90
+
91
+ 4a2 4 8a 8a 4 4a 4 8a 8a 4
92
+ 4a 4 8a 8a 4 4a 4 4a 8 8a
93
+ 4a 4 8a 8a 4 4a 4 8a 8a 4
94
+ 4a 4 8a 4 8a 4a 4 8a 4 8a
95
+
96
+ 4a2 4 8a 8a 4 4a 4 8a 8a 4
97
+ 4a 4 8a 8a 4 4a 4 4a 8 8a
98
+ 4a 4 8a 8a 4 4a 4 8a 8a 4
99
+ 4a 4 8a 4 8a 4a 4 8a 4 8a
100
+
101
+ 4a2 4 8a 8a 4 4a 4 8a 8a 4
102
+ 4a 4 8a 8a 4 4a 4 4a 8 8a
103
+ 4a 4 8a 8a 4 4a 4 8a 8a 4
104
+ 4a 4 8a 4 8a 4a 4 8a 4 8a
105
+ ^
106
+
107
+ b.tune snare, %q^
108
+ 4 4a2 4 4a2 4 4a2 4 4a2
109
+ 4 4a2 4 4a2 4 4a2 4 4a2
110
+ 4 4a2 4 4a2 4 4a2 4 4a2
111
+ 4 4a2 4 4a2 4 4a2 4 8a2 8a2
112
+
113
+ 4 4a2 4 4a2 4 4a2 4 4a2
114
+ 4 4a2 4 4a2 4 4a2 4 4a2
115
+ 4 4a2 4 4a2 4 4a2 4 4a2
116
+ 4 4a2 4 4a2 4 4a2 4 8a2 8a2
117
+
118
+ 4 4a2 4 4a2 4 4a2 4 4a2
119
+ 4 4a2 4 4a2 4 4a2 4 4a2
120
+ 4 4a2 4 4a2 4 4a2 4 4a2
121
+ 4 4a2 4 4a2 4 4a2 4 8a2 8a2
122
+
123
+ 4 4a2 4 4a2 4 4a2 4 4a2
124
+ 4 4a2 4 4a2 4 4a2 4 4a2
125
+ 4 4a2 4 4a2 4 4a2 4 4a2
126
+ 4 4a2 4 4a2 4 4a2 4 8a2 8a2
127
+ ^
128
+
129
+ b.tune chord, %q^
130
+ 1
131
+ 1 1
132
+ 1 1 1
133
+ 1 1
134
+
135
+ 1a2 2a3 2 1g2 2d3 2
136
+ 1a2 2a3 2 1d2 4g3 4g2 2e3
137
+
138
+ 1a2 2a3 2 1g2 2d3 2
139
+ 1a2 2a3 2 1d2 2g3 2
140
+
141
+ 1a2 2a3 2 1g2 2d3 2
142
+ 1a2 2a3 2 1d2 2g3 2
143
+
144
+ 1a2 2a3 2 1g2 2d3 2
145
+ 1a2 2a3 2 1d2 2g3 2
146
+ ^
147
+
148
+ b.tune chord, %q^
149
+ 1
150
+ 1 1
151
+ 1 1 1
152
+ 1 1
153
+
154
+ 2 2c4 2 1 2b4 2
155
+ 1 2c4 4 2g3 2b4 1
156
+
157
+ 2 2c4 2 1 2b4 2
158
+ 1 2c4 2 1 2b4 1
159
+
160
+ 2 2c4 2 1 2b4 2
161
+ 1 2c4 2 1 2b4 1
162
+
163
+ 2 2c4 2 1 2b4 2
164
+ 1 2c4 2 1 2b4 1
165
+ ^
166
+
167
+ b.tune chord, %q^
168
+ 1
169
+ 1 1
170
+ 1 1 1
171
+ 1 1
172
+
173
+ 2 1 2e4 2 1 2d4
174
+ 2 1 2e4 2 1 2d4
175
+
176
+ 2 1 2e4 2 1 2d4
177
+ 2 1 2e4 2 1 2d4
178
+
179
+ 2 1 2e4 2 1 2d4
180
+ 2 1 2e4 2 1 2d4
181
+
182
+ 2 1 2e4 2 1 2d4
183
+ 2 1 2e4 2 1 2d4
184
+ ^
185
+
186
+ b.tune lead, %q^
187
+ 1 4
188
+ 1 1 1 1
189
+ 1 1 1 1 1 1
190
+ 1 1 1 1
191
+
192
+ 2g3 1a4 2
193
+ 2c5 1e4 2 1
194
+ 1a4 2 4 2e4 1d4 2
195
+
196
+ 2a3 1b4 2
197
+ 2d5 2g4 1c5
198
+ 1a4 1e5
199
+ 1b4 2 4 8 8d4
200
+
201
+ 2g3 1a4 2
202
+ 2c5 1e4 3d4 5g4
203
+ 1a4 1e4
204
+ 1d4 1
205
+ ^
206
+
207
+ while true do
208
+ b.play
209
+ sleep 0.5 while not b.stopped?
210
+ end