scruby 0.2.7

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 (69) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +53 -0
  5. data/README.rdoc +65 -0
  6. data/Rakefile +10 -0
  7. data/TODO.markdown +3 -0
  8. data/examples/example.rb +73 -0
  9. data/lib/scruby/buffer.rb +153 -0
  10. data/lib/scruby/bus.rb +67 -0
  11. data/lib/scruby/control_name.rb +29 -0
  12. data/lib/scruby/core_ext/array.rb +44 -0
  13. data/lib/scruby/core_ext/delegator_array.rb +44 -0
  14. data/lib/scruby/core_ext/fixnum.rb +8 -0
  15. data/lib/scruby/core_ext/numeric.rb +25 -0
  16. data/lib/scruby/core_ext/object.rb +23 -0
  17. data/lib/scruby/core_ext/proc.rb +11 -0
  18. data/lib/scruby/core_ext/string.rb +5 -0
  19. data/lib/scruby/core_ext/symbol.rb +5 -0
  20. data/lib/scruby/core_ext/typed_array.rb +54 -0
  21. data/lib/scruby/env.rb +93 -0
  22. data/lib/scruby/group.rb +24 -0
  23. data/lib/scruby/node.rb +102 -0
  24. data/lib/scruby/server.rb +182 -0
  25. data/lib/scruby/synth.rb +50 -0
  26. data/lib/scruby/synthdef.rb +109 -0
  27. data/lib/scruby/ticker.rb +92 -0
  28. data/lib/scruby/ugens/buffer_read_write.rb +98 -0
  29. data/lib/scruby/ugens/demand.rb +9 -0
  30. data/lib/scruby/ugens/disk_in_out.rb +33 -0
  31. data/lib/scruby/ugens/env_gen.rb +38 -0
  32. data/lib/scruby/ugens/in_out.rb +46 -0
  33. data/lib/scruby/ugens/multi_out.rb +53 -0
  34. data/lib/scruby/ugens/operation_indices.yaml +92 -0
  35. data/lib/scruby/ugens/operation_ugens.rb +63 -0
  36. data/lib/scruby/ugens/panner.rb +137 -0
  37. data/lib/scruby/ugens/ugen.rb +173 -0
  38. data/lib/scruby/ugens/ugen_defs.yaml +3123 -0
  39. data/lib/scruby/ugens/ugen_operations.rb +57 -0
  40. data/lib/scruby/ugens/ugens.rb +95 -0
  41. data/lib/scruby/version.rb +3 -0
  42. data/lib/scruby.rb +65 -0
  43. data/scruby.gemspec +27 -0
  44. data/spec/buffer_read_write_spec.rb +333 -0
  45. data/spec/buffer_spec.rb +199 -0
  46. data/spec/bus_spec.rb +184 -0
  47. data/spec/core_ext/core_ext_spec.rb +120 -0
  48. data/spec/core_ext/delegator_array_spec.rb +144 -0
  49. data/spec/core_ext/typed_array_spec.rb +95 -0
  50. data/spec/demand_spec.rb +81 -0
  51. data/spec/disk_in_out_spec.rb +138 -0
  52. data/spec/env_gen_spec.rb +23 -0
  53. data/spec/env_spec.rb +73 -0
  54. data/spec/group_spec.rb +71 -0
  55. data/spec/helper.rb +20 -0
  56. data/spec/in_out_spec.rb +127 -0
  57. data/spec/integration_spec.rb +88 -0
  58. data/spec/multiout_ugen_spec.rb +86 -0
  59. data/spec/node_spec.rb +112 -0
  60. data/spec/operation_ugens_spec.rb +196 -0
  61. data/spec/panner_spec.rb +271 -0
  62. data/spec/server.rb +12 -0
  63. data/spec/server_spec.rb +198 -0
  64. data/spec/synth_spec.rb +103 -0
  65. data/spec/synthdef_spec.rb +267 -0
  66. data/spec/ugen_operations_spec.rb +100 -0
  67. data/spec/ugen_spec.rb +356 -0
  68. data/spec/ugens_spec.rb +65 -0
  69. metadata +207 -0
@@ -0,0 +1,267 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+
3
+ require "scruby/control_name"
4
+ require "scruby/core_ext/delegator_array"
5
+ require "scruby/env"
6
+ require "scruby/ugens/ugen"
7
+ require "scruby/ugens/ugen_operations"
8
+ require "scruby/synthdef"
9
+ require "scruby/ugens/multi_out"
10
+ require "scruby/core_ext/typed_array"
11
+
12
+ include Scruby
13
+ include Ugens
14
+
15
+ class MockUgen < Ugen
16
+ class << self; public :new; end
17
+ end
18
+
19
+
20
+ describe SynthDef, 'instantiation' do
21
+
22
+ describe 'initialize' do
23
+ before do
24
+ @sdef = SynthDef.new( :name ){}
25
+ @sdef.stub! :collect_control_names
26
+ end
27
+
28
+ it "should instantiate" do
29
+ @sdef.should_not be_nil
30
+ @sdef.should be_instance_of( SynthDef )
31
+ end
32
+
33
+ it "should protect attributes" do
34
+ @sdef.should_not respond_to( :name= )
35
+ @sdef.should_not respond_to( :children= )
36
+ @sdef.should_not respond_to( :constants= )
37
+ @sdef.should_not respond_to( :control_names= )
38
+
39
+ @sdef.should respond_to( :name )
40
+ @sdef.should respond_to( :children )
41
+ @sdef.should respond_to( :constants )
42
+ @sdef.should respond_to( :control_names )
43
+ end
44
+
45
+ it "should accept name and set it as an attribute as string" do
46
+ @sdef.name.should == 'name'
47
+ end
48
+
49
+ it "should initialize with an empty array for children" do
50
+ @sdef.children.should == []
51
+ end
52
+ end
53
+
54
+ describe "options" do
55
+ before do
56
+ @options = mock Hash
57
+ end
58
+
59
+ it "should accept options" do
60
+ sdef = SynthDef.new( :hola, :values => [] ){}
61
+ end
62
+
63
+ it "should use options" do
64
+ @options.should_receive(:delete).with :values
65
+ @options.should_receive(:delete).with :rates
66
+
67
+ sdef = SynthDef.new( :hola, @options ){}
68
+ end
69
+
70
+ it "should set default values if not provided"
71
+ it "should accept a graph function"
72
+
73
+ end
74
+
75
+ describe '#collect_control_names' do
76
+ before do
77
+ @sdef = SynthDef.new( :name ){}
78
+ @function = mock "grap_function", :arguments => [:arg1, :arg2, :arg3]
79
+ end
80
+
81
+ it "should get the argument names for the provided function" do
82
+ @function.should_receive( :arguments ).and_return []
83
+ @sdef.send_msg :collect_control_names, @function, [], []
84
+ end
85
+
86
+ it "should return empty array if the names are empty" do
87
+ @function.should_receive( :arguments ).and_return []
88
+ @sdef.send_msg( :collect_control_names, @function, [], [] ).should == []
89
+ end
90
+
91
+ it "should not return empty array if the names are not empty" do
92
+ @sdef.send_msg( :collect_control_names, @function, [], [] ).should_not == []
93
+ end
94
+
95
+ it "should instantiate and return a ControlName for each function name" do
96
+ c_name = mock :control_name
97
+ ControlName.should_receive( :new ).at_most(3).times.and_return c_name
98
+ control_names = @sdef.send_msg :collect_control_names, @function, [1,2,3], []
99
+ control_names.size.should == 3
100
+ control_names.collect { |e| e.should == c_name }
101
+ end
102
+
103
+ it "should pass the argument value, the argument index and the rate(if provided) to the ControlName at instantiation" do
104
+ cns = @sdef.send_msg :collect_control_names, @function, [1, 2, 3], []
105
+ cns.should == [1.0, 2.0, 3.0].map{ |val| ControlName.new("arg#{ val.to_i }", val, :control, val.to_i - 1 )}
106
+ cns = @sdef.send_msg :collect_control_names, @function, [1, 2, 3], [:ir, :tr, :ir]
107
+ cns.should == [[1.0, :ir], [2.0, :tr], [3.0, :ir]].map{ |val, rate| ControlName.new("arg#{ val.to_i }", val, rate, val.to_i - 1 )}
108
+ end
109
+
110
+ it "should not return more elements than the function argument number" do
111
+ @sdef.send_msg( :collect_control_names, @function, [1, 2, 3, 4, 5], [] ).should have( 3 ).elements
112
+ end
113
+ end
114
+
115
+ describe '#build_controls' do
116
+ before :all do
117
+ RATES = [:scalar, :trigger, :control]
118
+ end
119
+
120
+ before do
121
+ @sdef = SynthDef.new( :name ){}
122
+ @function = mock "grap_function", :arguments => [:arg1, :arg2, :arg3, :arg4]
123
+ @control_names = Array.new( rand(10)+15 ) { |i| ControlName.new "arg#{i+1}".to_sym, i, RATES[ rand(3) ], i }
124
+ end
125
+
126
+ it "should call Control#and_proxies.." do
127
+ rates = @control_names.collect{ |c| c.rate }.uniq
128
+ Control.should_receive(:and_proxies_from).exactly( rates.size ).times
129
+ @sdef.send_msg :build_controls, @control_names
130
+ end
131
+
132
+ it "should call Control#and_proxies.. with args" do
133
+ Control.should_receive(:and_proxies_from).with( @control_names.select{ |c| c.rate == :scalar } ) unless @control_names.select{ |c| c.rate == :scalar }.empty?
134
+ Control.should_receive(:and_proxies_from).with( @control_names.select{ |c| c.rate == :trigger } ) unless @control_names.select{ |c| c.rate == :trigger }.empty?
135
+ Control.should_receive(:and_proxies_from).with( @control_names.select{ |c| c.rate == :control } ) unless @control_names.select{ |c| c.rate == :control }.empty?
136
+ @sdef.send_msg( :build_controls, @control_names )
137
+ end
138
+
139
+ it do
140
+ @sdef.send_msg( :build_controls, @control_names ).should be_instance_of(Array)
141
+ end
142
+
143
+ it "should return an array of OutputProxies" do
144
+ @sdef.send_msg( :build_controls, @control_names ).each { |e| e.should be_instance_of(OutputProxy) }
145
+ end
146
+
147
+ it "should return an array of OutputProxies sorted by ControlNameIndex" do
148
+ @sdef.send_msg( :build_controls, @control_names ).collect{ |p| p.control_name.index }.should == (0...@control_names.size).to_a
149
+ end
150
+
151
+ it "should call graph function with correct args" do
152
+ function = mock("function", :call => [] )
153
+ proxies = @sdef.send_msg( :build_controls, @control_names )
154
+ @sdef.stub!( :build_controls ).and_return( proxies )
155
+ function.should_receive( :call ).with( *proxies )
156
+ @sdef.send_msg( :build_ugen_graph, function, @control_names)
157
+ end
158
+
159
+ it "should set @sdef" do
160
+ function = lambda{}
161
+ Ugen.should_receive( :synthdef= ).with( @sdef )
162
+ Ugen.should_receive( :synthdef= ).with( nil )
163
+ @sdef.send_msg( :build_ugen_graph, function, [] )
164
+ end
165
+
166
+ it "should collect constants for simple children array" do
167
+ children = [MockUgen.new(:audio, 100), MockUgen.new(:audio, 200), MockUgen.new(:audio, 100, 300)]
168
+ @sdef.send_msg( :collect_constants, children).should == [100.0, 200.0, 300.0]
169
+ end
170
+
171
+ it "should collect constants for children arrays" do
172
+ children = [ MockUgen.new(:audio, 100), [ MockUgen.new(:audio, 400), [ MockUgen.new(:audio, 200), MockUgen.new(:audio, 100, 300) ] ] ]
173
+ @sdef.send_msg( :collect_constants, children).should == [100.0, 400.0, 200.0, 300.0]
174
+ end
175
+
176
+ it "should remove nil from constants array"
177
+
178
+ end
179
+
180
+ end
181
+
182
+
183
+ describe "encoding" do
184
+
185
+ before :all do
186
+ class Spec::SinOsc < Ugen
187
+ def self.ar freq = 440.0, phase = 0.0 #not interested in muladd
188
+ new :audio, freq, phase
189
+ end
190
+ end
191
+ end
192
+
193
+ before do
194
+ @sdef = SynthDef.new(:hola) { Spec::SinOsc.ar }
195
+ @encoded = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 4, 104, 111, 108, 97, 0, 2, 67, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 0, 0 ].pack('C*')
196
+ end
197
+
198
+ it "should get values" do
199
+ @sdef.values
200
+ end
201
+
202
+ it "should encode init stream" do
203
+ @sdef.encode[0..9].should == @encoded[0..9]
204
+ end
205
+
206
+ it "should encode is, name" do
207
+ @sdef.encode[0..14].should == @encoded[0..14]
208
+ end
209
+
210
+ it "should encode is, name, constants" do
211
+ @sdef.encode[0..24].should == @encoded[0..24]
212
+ end
213
+
214
+ it "should encode is, name, consts, values" do
215
+ @sdef.encode[0..26].should == @encoded[0..26]
216
+ end
217
+
218
+ it "should encode is, name, consts, values, controls" do
219
+ @sdef.encode[0..28].should == @encoded[0..28]
220
+ end
221
+
222
+ it "should encode is, name, consts, values, controls, children" do
223
+ @sdef.encode[0..53].should == @encoded[0..53]
224
+ end
225
+
226
+ it "should encode is, name, consts, values, controls, children, variants stub" do
227
+ @sdef.encode.should == @encoded
228
+ end
229
+
230
+ describe "sending" do
231
+
232
+ before :all do
233
+ @server = mock('server', :instance_of? => true, :send_synth_def => nil)
234
+ ::Server = mock('Server', :all => [@server])
235
+ end
236
+
237
+ before do
238
+ @servers = (0..3).map{ mock('server', :instance_of? => true, :send_synth_def => nil) }
239
+ @sdef = SynthDef.new(:hola) { Spec::SinOsc.ar }
240
+ end
241
+
242
+ it "should accept an array or several Servers" do
243
+ @sdef.send @servers
244
+ @sdef.send *@servers
245
+ end
246
+
247
+ it "should not accept non servers" do
248
+ lambda{ @sdef.send [1, 2] }.should raise_error(NoMethodError)
249
+ lambda{ @sdef.send 1, 2 }.should raise_error(NoMethodError)
250
+ end
251
+
252
+ it "should send self to each of the servers" do
253
+ @servers.each{ |s| s.should_receive(:send_synth_def).with(@sdef) }
254
+ @sdef.send( @servers )
255
+ end
256
+
257
+ it "should send to Server.all if not provided with a list of servers" do
258
+ @server.should_receive(:send_synth_def).with(@sdef)
259
+ Server.should_receive(:all).and_return([@server])
260
+ @sdef.send
261
+ end
262
+ end
263
+ end
264
+
265
+
266
+
267
+
@@ -0,0 +1,100 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+ require 'yaml'
3
+
4
+ require "scruby/core_ext/delegator_array"
5
+ require "scruby/control_name"
6
+ require "scruby/env"
7
+ require "scruby/ugens/ugen"
8
+ require "scruby/ugens/operation_ugens"
9
+ require "scruby/ugens/ugen_operations"
10
+
11
+
12
+ include Scruby
13
+ include Ugens
14
+
15
+ class MockUgen < Ugen
16
+ class << self; public :new; end
17
+ end
18
+
19
+ describe UgenOperations do
20
+
21
+ before do
22
+ @ugen = MockUgen.new :audio
23
+ @ugen2 = MockUgen.new :audio
24
+ end
25
+
26
+ describe 'binary operations' do
27
+ it "should sum" do
28
+ sum = @ugen + @ugen2
29
+ sum.should be_instance_of(BinaryOpUGen)
30
+ end
31
+
32
+ it 'should sum integer' do
33
+ sum = @ugen + 1.0
34
+ sum.should be_instance_of(BinaryOpUGen)
35
+ end
36
+
37
+ it "should raise argument error" do
38
+ lambda { @ugen + :hola }.should raise_error(NoMethodError)
39
+ end
40
+ end
41
+
42
+ describe 'unary operations' do
43
+ it "should do unary op" do
44
+ op = @ugen.distort
45
+ op.should be_instance_of(UnaryOpUGen)
46
+ op.inputs.should == [@ugen]
47
+ end
48
+ end
49
+
50
+ describe Numeric do
51
+ it "do unary operation" do
52
+ 1.distort.should == UnaryOpUGen.new(:distort, 1)
53
+ end
54
+
55
+ it "should use original +" do
56
+ sum = 1 + 1
57
+ sum.should == 2
58
+ end
59
+
60
+ it "should set the correct inputs and operator for the binopugen" do
61
+ sum = 1.0 + @ugen
62
+ sum.should == BinaryOpUGen.new(:+, 1.0, @ugen)
63
+ end
64
+
65
+ it "ugen should sum numeric" do
66
+ sum = @ugen + 1
67
+ sum.should == BinaryOpUGen.new(:+, @ugen, 1)
68
+ end
69
+
70
+ it 'ugen should sum array' do
71
+ sum = @ugen * d(1,2)
72
+ sum.should == d(BinaryOpUGen.new(:*, @ugen, 1), BinaryOpUGen.new(:*, @ugen, 2))
73
+ end
74
+ end
75
+
76
+ describe DelegatorArray do
77
+ before do
78
+ @ugen = MockUgen.new :audio
79
+ end
80
+
81
+ it "do binary operation" do
82
+ d(@ugen).distort.should == d(@ugen.distort)
83
+ end
84
+
85
+ it "should do binary operation" do
86
+ op = d(1, 2) * @ugen
87
+ op.should be_a(DelegatorArray)
88
+ op.should == d(BinaryOpUGen.new(:*, 1, @ugen), BinaryOpUGen.new(:*, 2, @ugen))
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+
95
+ # methods overriden by UgenOperations inclusion:
96
+ # Fixnum#+ Fixnum#gcd Fixnum#/ Fixnum#round Fixnum#lcm Fixnum#div Fixnum#- Fixnum#>= Fixnum#* Fixnum#<=
97
+ # Float#+ Float#/ Float#round Float#div Float#- Float#>= Float#* Float#<=
98
+ # changed max and min to maximum and minimum because the override Array#max and Array#min wich take no args
99
+
100
+