maca-Scruby 0.0.8

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.
Files changed (43) hide show
  1. data/README.rdoc +26 -0
  2. data/Rakefile +10 -0
  3. data/Scruby.gemspec +36 -0
  4. data/bin/live_session.rb +12 -0
  5. data/changes +1 -0
  6. data/lib/live/session.rb +144 -0
  7. data/lib/scruby.rb +60 -0
  8. data/lib/scruby/audio/control_name.rb +29 -0
  9. data/lib/scruby/audio/env.rb +97 -0
  10. data/lib/scruby/audio/node.rb +20 -0
  11. data/lib/scruby/audio/server.rb +112 -0
  12. data/lib/scruby/audio/synth.rb +15 -0
  13. data/lib/scruby/audio/synthdef.rb +114 -0
  14. data/lib/scruby/audio/ugens/env_gen.rb +18 -0
  15. data/lib/scruby/audio/ugens/in_out.rb +43 -0
  16. data/lib/scruby/audio/ugens/multi_out_ugens.rb +48 -0
  17. data/lib/scruby/audio/ugens/operation_indices.yaml +92 -0
  18. data/lib/scruby/audio/ugens/operation_ugens.rb +64 -0
  19. data/lib/scruby/audio/ugens/ugen.rb +154 -0
  20. data/lib/scruby/audio/ugens/ugen_defs.yaml +3421 -0
  21. data/lib/scruby/audio/ugens/ugen_operations.rb +44 -0
  22. data/lib/scruby/audio/ugens/ugens.rb +34 -0
  23. data/lib/scruby/control/metro.rb +6 -0
  24. data/lib/scruby/extensions.rb +109 -0
  25. data/lib/scruby/typed_array.rb +64 -0
  26. data/spec/audio/env_gen_specs.rb +25 -0
  27. data/spec/audio/in_out_spec.rb +107 -0
  28. data/spec/audio/integration_spec.rb +106 -0
  29. data/spec/audio/lib_spec.rb +14 -0
  30. data/spec/audio/multiout_ugen_spec.rb +112 -0
  31. data/spec/audio/node_spec.rb +60 -0
  32. data/spec/audio/operation_ugens_spec.rb +189 -0
  33. data/spec/audio/server_spec.rb +68 -0
  34. data/spec/audio/synth_spec.rb +46 -0
  35. data/spec/audio/synthdef_spec.rb +275 -0
  36. data/spec/audio/ugen_operations_spec.rb +146 -0
  37. data/spec/audio/ugen_spec.rb +333 -0
  38. data/spec/audio/ugens_spec.rb +61 -0
  39. data/spec/env_spec.rb +64 -0
  40. data/spec/extensions_spec.rb +133 -0
  41. data/spec/helper.rb +11 -0
  42. data/spec/typed_array_spec.rb +95 -0
  43. metadata +129 -0
@@ -0,0 +1,333 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)), '..',"helper")
2
+ require 'yaml'
3
+
4
+ require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
5
+ require "#{SCRUBY_DIR}/audio/ugens/ugen"
6
+ require "#{SCRUBY_DIR}/extensions"
7
+
8
+ include Scruby
9
+ include Audio
10
+ include Ugens
11
+
12
+
13
+ class SinOsc < Ugen
14
+ class << self
15
+ def ar( freq=440.0, phase=0.0 ) #not interested in muladd
16
+ new(:audio, freq, phase)
17
+ end
18
+
19
+ def kr( freq=440.0, phase=0.0 )
20
+ new(:control, freq, phase)
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+ describe Ugen do
27
+
28
+ before do
29
+ @sdef = mock( 'sdef', :children => [] )
30
+ end
31
+
32
+ it "should set constants " do
33
+ UgenOperations::UNARY.should_not be_nil
34
+ UgenOperations::BINARY.should_not be_nil
35
+ Ugen::RATES.should_not be_nil
36
+ end
37
+
38
+ describe 'attributes' do
39
+
40
+ before do
41
+ @ugen = Ugen.new( :audio, 1 )
42
+ end
43
+
44
+ it do
45
+ @ugen.should respond_to( :inputs )
46
+ end
47
+
48
+ it do
49
+ @ugen.should respond_to( :rate )
50
+ end
51
+
52
+ it do
53
+ @ugen.should be_ugen
54
+ end
55
+ end
56
+
57
+ describe 'operations' do
58
+ before :all do
59
+ @op_ugen = mock( 'op_ugen', :ugen? => true )
60
+ BinaryOpUGen = mock( 'bynary_op_ugen', :new => @op_ugen )
61
+ UnaryOpUgen = mock( 'unary_op_ugen', :new => @op_ugen )
62
+ end
63
+
64
+ before do
65
+ @ugen = Ugen.new( :audio, 1, 2 )
66
+ @ugen2 = Ugen.new( :audio, 1, 2 )
67
+ end
68
+
69
+ it do #this specs all binary operations
70
+ @ugen.should respond_to( :+ )
71
+ end
72
+
73
+ it "should sum" do
74
+ BinaryOpUGen.should_receive( :new ).with( :+, @ugen, @ugen2)
75
+ @ugen + @ugen2
76
+ end
77
+ end
78
+
79
+ describe 'ugen graph in synth def' do
80
+ before do
81
+ Ugen.synthdef = nil
82
+ @ugen = Ugen.new( :audio, 1, 2 )
83
+ @ugen2 = Ugen.new( :audio, 1, 2 )
84
+ end
85
+
86
+ it "should not have synthdef" do
87
+ Ugen.new( :audio, 1, 2 ).send( :synthdef ).should be_nil
88
+ end
89
+
90
+ it "should have 0 as index if not belonging to ugen" do
91
+ Ugen.new( :audio, 1, 2 ).index.should be_zero
92
+ end
93
+
94
+ it "should have synthdef" do
95
+ Ugen.synthdef = @sdef
96
+ @ugen.send( :synthdef ).should == @sdef
97
+ end
98
+
99
+ it do
100
+ @ugen.should_not respond_to(:add_to_synthdef) #private method
101
+ end
102
+
103
+ it "should add to synth def on instantiation" do
104
+ Ugen.synthdef = @sdef
105
+ ugen = Ugen.new( :audio, 1, 2)
106
+ ugen.send( :synthdef ).should == @sdef
107
+ @sdef.children.should == [ugen]
108
+ end
109
+
110
+ it "should add to synthdef and return synthdef.children size" do
111
+ Ugen.synthdef = @sdef
112
+ ugen, ugen2 = Ugen.new(:audio, 1, 2), Ugen.new(:audio, 1, 2)
113
+ @sdef.children.should eql( [ugen, ugen2] )
114
+ ugen.index.should == 0
115
+ ugen2.index.should == 1
116
+ end
117
+
118
+ it "should not add to synthdef" do
119
+ Ugen.synthdef = nil
120
+ @sdef.children.should_not_receive( :<< )
121
+ Ugen.new( :audio, 1, 2 ).send( :add_to_synthdef ).should eql( nil )
122
+ end
123
+
124
+ it "should collect constants" do
125
+ Ugen.new( :audio, 100, @ugen, 200 ).send( :collect_constants ).flatten.sort.should == [1, 2, 100, 200]
126
+ end
127
+
128
+ it "should collect constants on arrayed inputs" do
129
+ Ugen.new( :audio, 100, [@ugen, [200, @ugen2, 100] ] ).send( :collect_constants ).flatten.uniq.sort.should == [1, 2, 100, 200]
130
+ end
131
+
132
+ end
133
+
134
+ describe 'initialization' do
135
+ before do
136
+ @ugen = Ugen.new(:audio, 1, 2, 3)
137
+ end
138
+
139
+ it "should not accept non valid inputs" do
140
+ lambda{ @ugen = Ugen.new(:audio, "hola") }.should raise_error( ArgumentError )
141
+ end
142
+
143
+ it "should require at least one argument" do
144
+ lambda { Ugen.new }.should raise_error( ArgumentError )
145
+ end
146
+
147
+ it "should be a defined rate as the first argument" do
148
+ lambda { Ugen.new( :not_a_rate, 1 ) }.should raise_error( ArgumentError )
149
+ end
150
+
151
+ it "should accept an empty array for inputs and inputs should be an empty array" do
152
+ Ugen.new( :audio, [] ).inputs.should eql([])
153
+ end
154
+
155
+ it "should instantiate" do
156
+ Ugen.new( :audio, 1, 2 ).should be_instance_of( Ugen )
157
+ end
158
+
159
+ it "should accept any number of args" do
160
+ Ugen.new( :audio, 1, 2 )
161
+ Ugen.new( :audio, 1, 2, 3, 4 )
162
+ end
163
+
164
+ it "should description" do
165
+ Ugen.should_receive( :instantiate ).with( :audio, 1, 2 )
166
+ Ugen.new( :audio, 1, 2 )
167
+ end
168
+
169
+ it "should set inputs" do
170
+ @ugen.inputs.should == [1, 2, 3]
171
+ end
172
+
173
+ it "should set rate" do
174
+ @ugen.rate.should == :audio
175
+ end
176
+
177
+ it "should have empty inputs" do
178
+ Ugen.new( :audio ).inputs.should == []
179
+ Ugen.new( :audio, [nil] ).inputs.should == []
180
+ end
181
+ end
182
+
183
+ describe 'initialization with array as argument' do
184
+
185
+ before :all do
186
+ *@i_1 = 100, 210
187
+ *@i_2 = 100, 220
188
+ *@i_3 = 100, 230
189
+ *@i_4 = 100, 240
190
+ end
191
+
192
+ it "should not care if an array was passed" do
193
+ Ugen.new( :audio, [1, 2, 3] ).should be_instance_of(Ugen)
194
+ end
195
+
196
+ it "should return an array of Ugens if an array as one arg is passed on instantiation" do
197
+ Ugen.new( :audio, 1, [2, 3] ).should be_instance_of(Array)
198
+ end
199
+
200
+ it do
201
+ Ugen.new( :audio, 1, [2,3], [4,5] ).should have( 2 ).items
202
+ end
203
+
204
+ it do
205
+ Ugen.new( :audio, 1, [2,3, 3], [4,5] ).should have( 3 ).items
206
+ end
207
+
208
+ it "should return an array of ugens" do
209
+ ugens = Ugen.new( :audio, 100, [210, 220, 230, 240] )
210
+ ugens.each do |u|
211
+ u.should be_instance_of(Ugen)
212
+ end
213
+ end
214
+
215
+ it "should return ugen" do
216
+ ugen = Ugen.new( :audio, [1], [2] )
217
+ ugen.should be_instance_of( Ugen )
218
+ ugen.inputs.should == [1, 2]
219
+ end
220
+
221
+ it "should return ugen" do
222
+ ugen = Ugen.new( :audio, [1, 2] )
223
+ ugen.should be_instance_of( Ugen )
224
+ ugen.inputs.should == [1, 2]
225
+ end
226
+
227
+ it "should instantiate when passing array" do
228
+ Ugen.should_receive(:instantiate).twice
229
+ ugen = Ugen.new( :audio, 100, [210, 220] )
230
+ end
231
+
232
+ it "should instantiate with correct arguments" do
233
+ Ugen.should_receive(:instantiate).with( :audio, *@i_1 )
234
+ Ugen.should_receive(:instantiate).with( :audio, *@i_2 )
235
+ Ugen.should_receive(:instantiate).with( :audio, *@i_3 )
236
+ Ugen.should_receive(:instantiate).with( :audio, *@i_4 )
237
+ ugens = Ugen.new( :audio, 100, [210, 220, 230, 240] )
238
+ ugens.should have(4).ugens
239
+ end
240
+
241
+ it "should return an array of ugens with correct inputs" do
242
+ ugens = Ugen.new( :audio, 100, [210, 220, 230, 240] )
243
+ ugens.zip( [@i_1, @i_2, @i_3, @i_4] ).each do |e|
244
+ e.first.inputs.should eql( e.last )
245
+ end
246
+ end
247
+
248
+ it "should match the structure of the inputs array(s)" do
249
+ array = [ 200, [210, [220, 230] ] ]
250
+ ugens = Ugen.new( :audio, 100, array )
251
+ last = lambda do |i|
252
+ if i.instance_of?(Ugen)
253
+ i.inputs.first.should == 100
254
+ i.inputs.last
255
+ else
256
+ i.map{ |e| last.call(e) }
257
+ end
258
+ end
259
+ last.call(ugens).should == array
260
+ end
261
+
262
+ it "should return muladd" do
263
+ MulAdd = mock( 'MulAdd', :new => nil )
264
+ @ugen = Ugen.new(:audio, 100, 100)
265
+ MulAdd.should_receive( :new ).with( @ugen, 1, 1)
266
+ @ugen.muladd(1, 1).should be_nil
267
+ end
268
+ end
269
+
270
+
271
+ end
272
+
273
+ describe Ugen, 'encoding' do
274
+
275
+ before do
276
+ args = [400.0, 0.0]
277
+ @sin = SinOsc.kr(*args)
278
+ @synthdef = mock('synthdef', :constants => args )
279
+ @sin.stub!(:index).and_return(1) #as if was the first child of a synthdef
280
+ @sin.stub!( :synthdef ).and_return( @synthdef )
281
+
282
+ @encoded = [6, 83, 105, 110, 79, 115, 99, 1, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 1].pack('C*')
283
+ end
284
+
285
+ it "should stub synthdef" do
286
+ @sin.send( :synthdef ).should == @synthdef
287
+ end
288
+
289
+ it "should encode have 0 as special index" do
290
+ @sin.send(:special_index).should == 0
291
+ end
292
+
293
+ it "should encode have 0 as output index" do
294
+ @sin.send(:output_index).should == 0
295
+ end
296
+
297
+ it "should encode have [1] as output index" do
298
+ @sin.send(:channels).should == [1]
299
+ end
300
+
301
+ it "should return input_specs" do
302
+ @sin.send( :input_specs, nil ).should == [1,0]
303
+ end
304
+
305
+ it "should collect input_specs" do
306
+ @sin.send(:collect_input_specs).should == [[-1, 0], [-1, 1]]
307
+ end
308
+
309
+ it "should collect input_specs" do
310
+ @sin.send(:collect_input_specs).flatten.collect { |e| e.encode }
311
+ end
312
+
313
+
314
+ it "should encode class name" do
315
+ @sin.encode[0..6].should == @encoded[0..6]
316
+ end
317
+
318
+ it "should encode classname, rate" do
319
+ @sin.encode[0..7].should == @encoded[0..7]
320
+ end
321
+
322
+ it "should encode cn, rt, inputs, channels, special_index" do
323
+ @sin.encode[0..13].should == @encoded[0..13]
324
+ end
325
+
326
+ it "should encode cn, rt, in, out, si, collect_input_specs" do
327
+ @sin.encode.should == @encoded
328
+ end
329
+
330
+
331
+ end
332
+
333
+
@@ -0,0 +1,61 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)), '..',"helper")
2
+ require 'yaml'
3
+ require 'named_arguments'
4
+
5
+ require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
6
+ require "#{SCRUBY_DIR}/audio/ugens/ugen"
7
+ require "#{SCRUBY_DIR}/audio/ugens/ugens"
8
+ require "#{SCRUBY_DIR}/extensions"
9
+
10
+
11
+ module UgenTest
12
+ end
13
+
14
+ class Klass
15
+ end
16
+
17
+ include Scruby
18
+ include Audio
19
+ include Ugens
20
+
21
+
22
+ describe Ugens do
23
+
24
+ before do
25
+ @udefs = YAML::load( File.open( "#{SCRUBY_DIR}/audio/ugens/ugen_defs.yaml" ) )
26
+ end
27
+
28
+ it do
29
+ @udefs.each_pair { |key, val| eval(key).should_not be_nil }
30
+ end
31
+
32
+ it do
33
+ @udefs.each_pair { |key, val| begin; eval(key).superclass.should eql( Scruby::Audio::Ugens::Ugen ); rescue; end }
34
+ end
35
+
36
+ it do
37
+ Vibrato.should respond_to(:ar)
38
+ Vibrato.should respond_to(:kr)
39
+ end
40
+
41
+ it do
42
+ Gendy1.should respond_to(:named_args_for)
43
+ end
44
+
45
+ it "should use default values" do
46
+ Gendy1.should_receive(:new).with( :audio, 1.0, 1.0, 1.0, 1.0, 440.0, 660.0, 0.5, 0.5, 12.0, nil ).and_return( mock('ugen', :muladd => nil) )
47
+ Gendy1.ar
48
+ end
49
+
50
+ it "should accept named args" do
51
+ ugen = mock('ugen')
52
+ ugen.should_receive( :muladd ).with(2,3)
53
+ Gendy1.should_receive(:new).with( :audio, 4, 5, 6, 1.0, 440.0, 660.0, 0.5, 0.5, 12.0, 100 ).and_return( ugen )
54
+ Gendy1.ar( 4, 5, 6, :knum => 100, :mul => 2, :add => 3 )
55
+ end
56
+
57
+ it "should work with arrays"
58
+
59
+ end
60
+
61
+
data/spec/env_spec.rb ADDED
@@ -0,0 +1,64 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)),"helper")
2
+
3
+ require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
4
+ require "#{SCRUBY_DIR}/extensions"
5
+ require 'named_arguments'
6
+ require "#{SCRUBY_DIR}/audio/env"
7
+
8
+
9
+ describe Env do
10
+
11
+ it "Env.new([0,1,0], [0.5, 1])" do
12
+ env = Env.new([0,1,0], [0.5, 1])
13
+ env.times.should == [0.5, 1]
14
+ env.levels.should == [ 0, 1, 0 ]
15
+ env.shape_numbers.should == [1]
16
+ env.curve_values.should == [0]
17
+ end
18
+
19
+ it do
20
+ env = Env.new([0,1,0], [0.5, 1])
21
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 2, -99, -99, 1, 0.5, 1, 0, 0, 1, 1, 0 ].collect{ |i| i.to_f }
22
+ end
23
+
24
+ it do
25
+ Env.perc.should be_instance_of( Env )
26
+ end
27
+
28
+ it "#perc" do
29
+ perc = Env.perc
30
+ perc.to_array.collect{ |i| i.to_f }.should == [ 0, 2, -99, -99, 1, 0.01, 5, -4, 0, 1, 5, -4 ].collect{ |i| i.to_f }
31
+ p perc.to_array
32
+ end
33
+
34
+ it '#sine' do
35
+ env = Env.sine
36
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 2, -99, -99, 1, 0.5, 3, 0, 0, 0.5, 3, 0 ].collect{ |i| i.to_f }
37
+ end
38
+
39
+ it "#linen" do
40
+ env = Env.linen
41
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 3, -99, -99, 1, 0.01, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0 ].collect{ |i| i.to_f }
42
+ end
43
+
44
+ it "#triangle" do
45
+ env = Env.triangle
46
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 2, -99, -99, 1, 0.5, 1, 0, 0, 0.5, 1, 0 ].collect{ |i| i.to_f }
47
+ end
48
+
49
+ it "#cutoff" do
50
+ env = Env.cutoff
51
+ env.to_array.collect{ |i| i.to_f }.should == [ 1, 1, 0, -99, 0, 0.1, 1, 0 ].collect{ |i| i.to_f }
52
+ end
53
+
54
+ it "#dadsr" do
55
+ env = Env.dadsr
56
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 4, 3, -99, 0, 0.1, 5, -4, 1, 0.01, 5, -4, 0.5, 0.3, 5, -4, 0, 1, 5, -4 ].collect{ |i| i.to_f }
57
+ end
58
+
59
+ it "#dadsr" do
60
+ env = Env.adsr
61
+ env.to_array.collect{ |i| i.to_f }.should == [ 0, 3, 2, -99, 1, 0.01, 5, -4, 0.5, 0.3, 5, -4, 0, 1, 5, -4 ].collect{ |i| i.to_f }
62
+ end
63
+
64
+ end