ruck 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +0,0 @@
1
-
2
- class Object
3
- def linkable_attr(attr_sym)
4
- attr_reader attr_sym
5
- define_method("#{attr_sym}=") do |val|
6
- instance_variable_set("@#{attr_sym}", val)
7
- if val.respond_to? :call
8
- meta_def attr_sym do
9
- val.call
10
- end
11
- else
12
- meta_def attr_sym do
13
- val
14
- end
15
- end
16
- end
17
- end
18
-
19
- def L(&block)
20
- block
21
- end
22
- end
@@ -1,18 +0,0 @@
1
- # stolen from:
2
- # http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
3
-
4
- class Object
5
- # The hidden singleton lurks behind everyone
6
- def metaclass; class << self; self; end; end
7
- def meta_eval &blk; metaclass.instance_eval &blk; end
8
-
9
- # Adds methods to a metaclass
10
- def meta_def name, &blk
11
- meta_eval { define_method name, &blk }
12
- end
13
-
14
- # Defines an instance method within a class
15
- def class_def name, &blk
16
- class_eval { define_method name, &blk }
17
- end
18
- end
@@ -1,29 +0,0 @@
1
-
2
- module RuckTime
3
- def sample
4
- self
5
- end
6
- alias_method :samples, :sample
7
-
8
- def ms
9
- self.to_f * SAMPLE_RATE / 1000.0
10
- end
11
-
12
- def second
13
- self.to_f * SAMPLE_RATE
14
- end
15
- alias_method :seconds, :second
16
-
17
- def minute
18
- self.to_f * SAMPLE_RATE * 60.0
19
- end
20
- alias_method :minutes, :minute
21
- end
22
-
23
- class Fixnum
24
- include RuckTime
25
- end
26
-
27
- class Float
28
- include RuckTime
29
- end
@@ -1,71 +0,0 @@
1
-
2
- module Riff
3
-
4
- class RiffReaderChunk
5
- attr_reader :data_start
6
- attr_accessor :data_skip
7
-
8
- def initialize(fn, start)
9
- @fn, @start = fn, start
10
- @size_start = @start + 4
11
- @data_start = @start + 8
12
- @data_skip = 0
13
- end
14
-
15
- def type
16
- return @type if @type
17
- @fn.seek @start
18
- @type = @fn.read(4)
19
- end
20
-
21
- def size
22
- return @size - @data_skip if @size
23
- @fn.seek @size_start
24
- @size = @fn.read(4).unpack("L")[0]
25
- @size - @data_skip
26
- end
27
-
28
- # pass a Range of bytes, or start and length
29
- def [](*args)
30
- first, last = case args.length
31
- when 1; [args.first.begin, args.first.end]
32
- when 2; [args[0], args[0] + args[1]]
33
- end
34
- @fn.seek @data_start + @data_skip + first
35
- @fn.read(last - first + 1)
36
- end
37
-
38
- def chunks
39
- offset = @data_start + @data_skip
40
- chunks = []
41
- while offset + @data_skip - @data_start < size
42
- chunks << chunk = RiffReaderChunk.new(@fn, offset)
43
- offset += @data_start + chunk.size
44
- end
45
- chunks
46
- end
47
-
48
- def to_s
49
- "<RiffHeader type:#{type} size:#{size}>"
50
- end
51
-
52
- end
53
-
54
- class RiffReader
55
- def initialize(filename)
56
- @fn = File.open(filename, "rb")
57
- end
58
-
59
- def chunks
60
- offset = 0
61
- chunks = []
62
- until @fn.eof?
63
- chunks << chunk = RiffReaderChunk.new(@fn, offset)
64
- offset += 8 + chunk.size
65
- @fn.seek offset + 8
66
- end
67
- chunks
68
- end
69
- end
70
-
71
- end
@@ -1,35 +0,0 @@
1
- # stolen from
2
- # http://www.mokehehe.com/assari/index.php?WAV%A5%D5%A5%A1%A5%A4%A5%EB%C6%E2%A4%CE%A5%C1%A5%E3%A5%F3%A5%AF%A4%F2%CE%F3%B5%F3%A4%B9%A4%EB
3
-
4
- if ARGV.length < 1
5
- print "usage: [input wav filename]\n"
6
- exit
7
- end
8
-
9
- inwavfn = ARGV[0]
10
-
11
- File::open(inwavfn, "rb") {|f|
12
- riff = f.read(4)
13
- if riff != 'RIFF'
14
- STDERR.print "not RIFF\n"
15
- exit
16
- end
17
- totalsizestr = f.read(4)
18
- totalsize = totalsizestr.unpack("L")[0]
19
-
20
- wave = f.read(4)
21
- if wave != 'WAVE'
22
- STDERR.print "not WAVE\n"
23
- exit
24
- end
25
-
26
- while !f.eof
27
- chk = f.read(4)
28
- chksizestr = f.read(4)
29
- chksize = chksizestr.unpack("L")[0]
30
-
31
- print chk, ",#{chksize}\n"
32
-
33
- f.seek(chksize, IO::SEEK_CUR)
34
- end
35
- }
@@ -1,408 +0,0 @@
1
-
2
- module Ruck
3
-
4
- module UGen
5
-
6
- def to_s
7
- "<#{self.class}" +
8
- (name ? "(#{name})" : "") +
9
- " #{attr_names.map { |a| "#{a}:#{send a}" }.join " "}>"
10
- end
11
-
12
- attr_accessor :name
13
-
14
- protected
15
-
16
- def require_attrs(attrs, names)
17
- names.each do |name|
18
- unless attrs.has_key? name
19
- raise "#{self} requires attribute #{name}"
20
- end
21
- end
22
- end
23
-
24
- def parse_attrs(attrs)
25
- attrs.each do |attr, value|
26
- send("#{attr}=", value)
27
- end
28
- end
29
-
30
- def pop_attrs(attrs, names)
31
- names.map { |name| attrs.delete(name) }
32
- end
33
-
34
- end
35
-
36
- module Target
37
- def add_source(ugen)
38
- if ugen.is_a? Array
39
- ugen.each { |u| add_source u }
40
- else
41
- @ins << ugen
42
- end
43
-
44
- self
45
- end
46
-
47
- def remove_source(ugen)
48
- if ugen.is_a? Array
49
- ugen.each { |u| remove_source u }
50
- else
51
- @ins.delete(ugen)
52
- end
53
-
54
- self
55
- end
56
- end
57
-
58
- module MultiChannelTarget
59
- def add_source(ugen)
60
- if ugen.is_a? Array
61
- ugen.each { |u| add_source u }
62
- return self
63
- end
64
-
65
- if ugen.out_channels.length == 1
66
- @in_channels.each { |chan| chan.add_source ugen.out(0) }
67
- else
68
- 1.upto([ugen.out_channels.length, @in_channels.length].min) do |i|
69
- @in_channels[i-1].add_source ugen.out(i-1)
70
- end
71
- end
72
-
73
- self
74
- end
75
-
76
- def remove_source(ugen)
77
- if ugen.is_a? Array
78
- ugen.each { |u| remove_source u }
79
- return
80
- end
81
-
82
- # remove all outputs of ugen from all inputs of self
83
- @in_channels.each do |in_chan|
84
- ugen.out_channels.each do |out_chan|
85
- in_chan.remove_source out_chan
86
- end
87
- end
88
-
89
- self
90
- end
91
-
92
- def in_channels
93
- @in_channels
94
- end
95
-
96
- def in(chan)
97
- @in_channels[chan]
98
- end
99
- end
100
-
101
- module Source
102
- def >>(ugen)
103
- ugen.add_source self
104
- end
105
-
106
- def <<(ugen)
107
- ugen.remove_source self
108
- end
109
-
110
- def out_channels
111
- [self]
112
- end
113
-
114
- def out(chan)
115
- self if chan == 0
116
- end
117
-
118
- def next(now); @last; end
119
- def last; @last; end
120
- end
121
-
122
- module MultiChannelSource
123
- def >>(ugen)
124
- ugen.add_source self
125
- end
126
-
127
- def <<(ugen)
128
- ugen.remove_source self
129
- end
130
-
131
- def out_channels
132
- @out_channels
133
- end
134
-
135
- def out(chan)
136
- @out_channels[chan]
137
- end
138
-
139
- def next(now, chan = 0); @last[chan]; end
140
- def last(chan = 0); @last[chan]; end
141
- end
142
-
143
- class InChannel
144
- include UGen
145
- include Target
146
-
147
- def initialize(attrs = {})
148
- parse_attrs attrs
149
- @ins = []
150
- @last = 0.0
151
- end
152
-
153
- def next(now)
154
- return @last if @now == now
155
- @now = now
156
- @last = @ins.inject(0) { |samp, ugen| samp += ugen.next(now) }
157
- end
158
-
159
- def attr_names
160
- []
161
- end
162
- end
163
-
164
- class OutChannel
165
- include Source
166
-
167
- def initialize(parent, channel_number)
168
- @parent = parent
169
- @channel_number = channel_number
170
- end
171
-
172
- def next(now)
173
- return @last if @now == now
174
- @last = @parent.next(now, @channel_number)
175
- end
176
- end
177
-
178
- module Generators
179
-
180
- class Gain
181
- include UGen
182
- include Source
183
- include Target
184
-
185
- linkable_attr :gain
186
-
187
- def initialize(attrs = {})
188
- parse_attrs({ :gain => 1.0 }.merge(attrs))
189
- @ins = []
190
- @last = 0.0
191
- end
192
-
193
- def next(now)
194
- return @last if @now == now
195
- @now = now
196
- @last = @ins.inject(0) { |samp, ugen| samp += ugen.next(now) } * gain
197
- end
198
-
199
- def attr_names
200
- [:gain]
201
- end
202
- end
203
-
204
- class Step
205
- include UGen
206
- include Source
207
-
208
- linkable_attr :value
209
-
210
- def initialize(attrs = {})
211
- parse_attrs({ :value => 0.0 }.merge(attrs))
212
- @last = value
213
- end
214
-
215
- def next(now)
216
- return @last if @now == now
217
- @now = now
218
- @last = value
219
- end
220
-
221
- def attr_names
222
- [:value]
223
- end
224
- end
225
-
226
- class Delay
227
- include UGen
228
- include Target
229
- include Source
230
-
231
- linkable_attr :gain
232
-
233
- def initialize(attrs = {})
234
- require_attrs attrs, [:time]
235
- samples = attrs.delete(:time)
236
- parse_attrs attrs
237
- @ins = []
238
- @last = 0.0
239
- @queue = [0.0] * samples
240
- end
241
-
242
- def next(now)
243
- return @last if @now == now
244
- @now = now
245
-
246
- @queue << @ins.inject(0) { |samp, ugen| samp += ugen.next(now) } * gain
247
- @last = @queue.shift
248
- end
249
-
250
- def attr_names
251
- [:time]
252
- end
253
- end
254
-
255
- class Noise
256
- include UGen
257
- include Source
258
-
259
- linkable_attr :gain
260
-
261
- def initialize(attrs = {})
262
- parse_attrs({ :gain => 1.0 }.merge(attrs))
263
- @last = 0.0
264
- end
265
-
266
- def next(now)
267
- return @last if @now == now
268
- @now = now
269
- @last = rand * gain
270
- end
271
-
272
- def attr_names
273
- [:gain]
274
- end
275
- end
276
-
277
- class Ramp
278
- include UGen
279
- include Source
280
-
281
- linkable_attr :from
282
- linkable_attr :to
283
- linkable_attr :duration
284
- linkable_attr :progress
285
- linkable_attr :paused
286
-
287
- def initialize(attrs = {})
288
- parse_attrs({ :from => 0.0,
289
- :to => 1.0,
290
- :duration => 1.second }.merge(attrs))
291
- @progress = 0.0
292
- @paused = false
293
- @last = 0.0
294
- end
295
-
296
- def next(now)
297
- return @last if @now == now
298
- @now = now
299
- @last = progress * (to - from) + from
300
- inc_progress
301
- @last
302
- end
303
-
304
- def reverse
305
- @from, @to = @to, @from
306
- end
307
-
308
- def reset
309
- @progress = 0.0
310
- end
311
-
312
- def finished?
313
- progress == 1.0
314
- end
315
-
316
- def attr_names
317
- [:from, :to, :duration, :progress, :paused]
318
- end
319
-
320
- protected
321
-
322
- def inc_progress
323
- return if @paused
324
- @progress += 1.0 / duration
325
- @progress = 1.0 if @progress > 1.0
326
- end
327
-
328
- end
329
-
330
- class ADSR
331
- include UGen
332
- include Target
333
- include Source
334
-
335
- attr_accessor :attack_time
336
- attr_accessor :attack_gain
337
- attr_accessor :decay_time
338
- attr_accessor :sustain_gain
339
- attr_accessor :release_time
340
-
341
- def initialize(attrs = {})
342
- parse_attrs({ :attack_time => 50.ms,
343
- :attack_gain => 1.0,
344
- :decay_time => 50.ms,
345
- :sustain_gain => 0.5,
346
- :release_time => 500.ms }.merge(attrs))
347
-
348
- @ramp = Ramp.new
349
-
350
- @ins = []
351
- @last = 0.0
352
- @gain = 0.0
353
- @state = :idle
354
- end
355
-
356
- def next(now)
357
- return @last if @now == now
358
- @now = now
359
- @gain = case @state
360
- when :idle
361
- 0
362
- when :attack
363
- if @ramp.finished?
364
- @ramp.reset
365
- @ramp.from, @ramp.to = @ramp.last, @sustain_gain
366
- @ramp.duration = @decay_time
367
- @state = :decay
368
- end
369
- @ramp.next(now)
370
- when :decay
371
- @state = :sustain if @ramp.finished?
372
- @ramp.next(now)
373
- when :sustain
374
- @sustain_gain
375
- when :release
376
- @state = :idle if @ramp.finished?
377
- @ramp.next(now)
378
- end
379
- @last = @ins.inject(0) { |samp, ugen| samp += ugen.next(now) } * @gain
380
- end
381
-
382
- def on
383
- @ramp.reset
384
- @ramp.from, @ramp.to = @gain, @attack_gain
385
- @ramp.duration = @attack_time
386
- @state = :attack
387
- end
388
-
389
- def off
390
- @ramp.reset
391
- @ramp.from, @ramp.to = @gain, 0
392
- @ramp.duration = @release_time
393
- @state = :release
394
- end
395
-
396
- def attr_names
397
- [:attack_time, :attack_gain, :decay_time, :sustain_gain, :release_time]
398
- end
399
-
400
- end
401
- end
402
-
403
- end
404
-
405
- # Allow chucking all elements of an array to
406
- class Array
407
- include Ruck::Source
408
- end
@@ -1,106 +0,0 @@
1
-
2
- module Ruck
3
-
4
- module Oscillator
5
- include UGen
6
- TWO_PI = 2 * Math::PI
7
-
8
- def self.included(base)
9
- base.instance_eval do
10
- linkable_attr :freq
11
- linkable_attr :phase
12
- end
13
- end
14
-
15
- def phase_forward
16
- @phase = (@phase + freq.to_f / SAMPLE_RATE.to_f) % 1.0
17
- end
18
- end
19
-
20
- module Generators
21
-
22
- class SinOsc
23
- include Source
24
- include Oscillator
25
-
26
- linkable_attr :freq
27
- linkable_attr :gain
28
-
29
- def initialize(attrs = {})
30
- parse_attrs({ :freq => 440.0,
31
- :gain => 1.0 }.merge(attrs))
32
- @phase = 0.0
33
- @last = 0.0
34
- end
35
-
36
- def next(now)
37
- return @last if @now == now
38
- @now = now
39
- @last = gain * Math.sin(phase * TWO_PI)
40
- phase_forward
41
- @last
42
- end
43
-
44
- def attr_names
45
- [:freq, :gain, :phase]
46
- end
47
- end
48
-
49
- class SawOsc
50
- include Source
51
- include Oscillator
52
-
53
- linkable_attr :gain
54
-
55
- def initialize(attrs = {})
56
- parse_attrs({ :freq => 440.0,
57
- :gain => 1.0 }.merge(attrs))
58
- @phase = 0.0
59
- @last = 0.0
60
- end
61
-
62
- def next(now)
63
- return @last if @now == now
64
- @now = now
65
- @last = ((phase * 2.0) - 1.0) * gain
66
- phase_forward
67
- @last
68
- end
69
-
70
- def attr_names
71
- [:freq, :gain, :phase]
72
- end
73
- end
74
-
75
- class TriOsc
76
- include Source
77
- include Oscillator
78
-
79
- linkable_attr :gain
80
-
81
- def initialize(attrs = {})
82
- parse_attrs({ :freq => 440.0,
83
- :gain => 1.0 }.merge(attrs))
84
- @phase = 0.0
85
- @last = 0.0
86
- end
87
-
88
- def next(now)
89
- return @last if @now == now
90
- @now = now
91
- @last = if phase < 0.5
92
- phase * 4.0 - 1.0
93
- else
94
- 1.0 - ((phase - 0.5) * 4.0)
95
- end * gain
96
- phase_forward
97
- @last
98
- end
99
-
100
- def attr_names
101
- [:freq, :gain, :phase]
102
- end
103
- end
104
-
105
- end
106
- end