bloops 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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