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,88 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+
3
+ require "scruby"
4
+
5
+ include Scruby
6
+ include Ugens
7
+
8
+ describe "synthdef examples" do
9
+
10
+ before :all do
11
+ @sdef = SynthDef.new :hola do |a, b| SinOsc.kr( a ) + SinOsc.kr( b ) end
12
+ @expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 4, 104, 111, 108, 97, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 97, 0, 0, 1, 98, 0, 1, 0, 4, 7, 67, 111, 110, 116, 114, 111, 108, 1, 0, 0, 0, 2, 0, 0, 1, 1, 6, 83, 105, 110, 79, 115, 99, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 1, 6, 83, 105, 110, 79, 115, 99, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 1, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 1, 0, 2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0 ].pack('C*')
13
+ end
14
+
15
+ it "should have correct children" do
16
+ @sdef.children[0].should be_instance_of( Control )
17
+ @sdef.children[1].should be_instance_of( SinOsc )
18
+ @sdef.children[2].should be_instance_of( SinOsc )
19
+ @sdef.children[3].should be_instance_of( BinaryOpUGen )
20
+ end
21
+
22
+ it "should encode with control" do
23
+ @sdef.encode.should == @expected
24
+ end
25
+
26
+ it "should encode with ops" do
27
+ expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 4, 104, 101, 108, 112, 0, 2, 67, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 2, 0, 0, 0, 3, 0, 0, 2, 0, 0 ].pack('C*')
28
+ SynthDef.new(:help){ (SinOsc.ar() + SinOsc.ar()) * SinOsc.ar() }.encode.should == expected
29
+ end
30
+
31
+ it "should encode with out" do
32
+ sdef = SynthDef.new(:out){ Out.ar(0, SinOsc.ar) }
33
+ sdef.children.should have(2).children
34
+
35
+ sdef.children[0].should be_instance_of( SinOsc )
36
+ sdef.children[1].should be_instance_of( Out )
37
+
38
+ sdef.constants.should == [ 440, 0 ]
39
+ sdef.children[1].channels.should == []
40
+
41
+ expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 3, 111, 117, 116, 0, 2, 67, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 3, 79, 117, 116, 2, 0, 2, 0, 0, 0, 0, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0 ].pack('C*')
42
+ sdef.encode.should == expected
43
+ end
44
+
45
+ it "should encode another with out" do
46
+ sdef = SynthDef.new(:out){ sig = SinOsc.ar(100, 200) * SinOsc.ar(200); Out.ar(0, sig) }
47
+ sdef.encode.should == [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 3, 111, 117, 116, 0, 3, 66, -56, 0, 0, 67, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 1, -1, -1, 0, 2, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3, 79, 117, 116, 2, 0, 2, 0, 0, 0, 0, -1, -1, 0, 2, 0, 2, 0, 0, 0, 0 ].pack('C*')
48
+ end
49
+
50
+ it "should encode out with two channels" do
51
+ sdef = SynthDef.new( :out ){ sig = SinOsc.ar(100, [200, 200]) * SinOsc.ar(200); Out.ar(0, sig) }
52
+ expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 3, 111, 117, 116, 0, 3, 66, -56, 0, 0, 67, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 1, -1, -1, 0, 2, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 2, 0, 0, 2, 3, 79, 117, 116, 2, 0, 3, 0, 0, 0, 0, -1, -1, 0, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0 ].pack('C*')
53
+ sdef.encode.should == expected
54
+ end
55
+
56
+ it "should instantiate and encode" do
57
+ expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 4, 104, 101, 108, 112, 0, 2, 67, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 2, 0, 0, 0, 3, 0, 0, 2, 0, 0 ].pack('C*')
58
+ SynthDef.new( :help ){ (SinOsc.ar() + SinOsc.ar()) * SinOsc.ar() }.encode.should == expected
59
+ end
60
+
61
+ it "should encode out with multidimensional array" do
62
+ sdef = SynthDef.new( :out ){ sig = SinOsc.ar(100, [200,[100, 100]]) * SinOsc.ar(200); Out.ar(0, sig) }
63
+ children = sdef.children
64
+ children[0..3].map { |u| u.should be_instance_of(SinOsc) }
65
+ children[4].should be_instance_of(BinaryOpUGen)
66
+ children[5].should be_instance_of(BinaryOpUGen)
67
+ children[6].should be_instance_of(BinaryOpUGen)
68
+ children[7].should be_instance_of(Out)
69
+ children[8].should be_instance_of(Out)
70
+ #the order of the elements is different than in supercollider, but at least has the encoded string is the same size so i guess its fine
71
+ sdef.encode.should have(261).chars
72
+ end
73
+
74
+ it "should encode 'complex' sdef" do
75
+ sdef = SynthDef.new :am do |gate, portadora, moduladora, amp|
76
+ mod = SinOsc.kr moduladora, 0, 0.5, 0.5
77
+ sig = SinOsc.ar portadora, 0, mod
78
+ env = EnvGen.kr Env.asr(2, 1, 2), gate, :doneAction => 2
79
+ Out.ar 0, sig*env
80
+ end
81
+
82
+ sdef.children.should have(8).children
83
+ sdef.constants.should == [0, 0.5, 1, 2, -99, 5, -4]
84
+ expected = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 2, 97, 109, 0, 7, 0, 0, 0, 0, 63, 0, 0, 0, 63, -128, 0, 0, 64, 0, 0, 0, -62, -58, 0, 0, 64, -96, 0, 0, -64, -128, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 103, 97, 116, 101, 0, 0, 9, 112, 111, 114, 116, 97, 100, 111, 114, 97, 0, 1, 10, 109, 111, 100, 117, 108, 97, 100, 111, 114, 97, 0, 2, 3, 97, 109, 112, 0, 3, 0, 8, 7, 67, 111, 110, 116, 114, 111, 108, 1, 0, 0, 0, 4, 0, 0, 1, 1, 1, 1, 6, 83, 105, 110, 79, 115, 99, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 2, -1, -1, 0, 0, 1, 6, 77, 117, 108, 65, 100, 100, 1, 0, 3, 0, 1, 0, 0, 0, 1, 0, 0, -1, -1, 0, 1, -1, -1, 0, 1, 1, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 3, 0, 0, 0, 2, 0, 0, 2, 6, 69, 110, 118, 71, 101, 110, 1, 0, 17, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 2, -1, -1, 0, 0, -1, -1, 0, 2, -1, -1, 0, 3, -1, -1, 0, 0, -1, -1, 0, 3, -1, -1, 0, 2, -1, -1, 0, 4, -1, -1, 0, 2, -1, -1, 0, 3, -1, -1, 0, 5, -1, -1, 0, 6, -1, -1, 0, 0, -1, -1, 0, 3, -1, -1, 0, 5, -1, -1, 0, 6, 1, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 4, 0, 0, 0, 5, 0, 0, 2, 3, 79, 117, 116, 2, 0, 2, 0, 0, 0, 0, -1, -1, 0, 0, 0, 6, 0, 0, 0, 0 ].pack('c*')
85
+ sdef.encode.should == expected
86
+ end
87
+ end
88
+
@@ -0,0 +1,86 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+
3
+ require "scruby/core_ext/delegator_array"
4
+ require "scruby/control_name"
5
+ require "scruby/env"
6
+ require "scruby/ugens/ugen"
7
+ require "scruby/ugens/ugen_operations"
8
+ require "scruby/ugens/multi_out"
9
+
10
+ include Scruby
11
+ include Ugens
12
+
13
+ class Control
14
+ class << self
15
+ public :new
16
+ end
17
+ end
18
+
19
+ describe Control do
20
+ before do
21
+ sdef = mock( 'SynthDef', :children => [] )
22
+ Ugen.stub!( :synthdef ).and_return( sdef )
23
+
24
+ @proxy = mock(OutputProxy, :instance_of_proxy? => true)
25
+ OutputProxy.stub!( :new ).and_return( @proxy )
26
+
27
+ @names = Array.new( rand(7) + 3 ) do |i|
28
+ ControlName.new "control_#{i}", 1, :control, i
29
+ end
30
+
31
+ @proxies = Control.new( :audio, *@names )
32
+ @control = sdef.children.first
33
+ end
34
+
35
+ it "should return an array of proxies" do
36
+ @proxies.should be_a( DelegatorArray )
37
+ @proxies.should have( @names.size ).proxies
38
+ end
39
+
40
+ it "should set channels" do
41
+ @control.should be_instance_of( Control )
42
+ @control.channels.should == @names.map{ @proxy }
43
+ end
44
+
45
+ it "should be added to synthdef" do
46
+ Ugen.should_receive( :synthdef )
47
+ Control.new( :audio, [])
48
+ end
49
+
50
+ it "should instantiate with #and_proxies_from" do
51
+ Control.should_receive(:new).with( :control, *@names )
52
+ Control.and_proxies_from( @names )
53
+ end
54
+
55
+ it "should have index" do
56
+ @control.index.should == 0
57
+ end
58
+
59
+ end
60
+
61
+ describe OutputProxy do
62
+
63
+ before do
64
+ @sdef = mock( 'sdef', :children => [] )
65
+ Ugen.stub!( :synthdef ).and_return( @sdef )
66
+ @name = ControlName.new( "control", 1, :control, 0)
67
+ @names = [@name]
68
+ @output_index = 1
69
+ end
70
+
71
+ it "should receive index from control" do
72
+ Control.and_proxies_from( @names ).first.index.should == 0
73
+ @sdef.children.first.index.should == 0
74
+ end
75
+
76
+ it "should have empty inputs" do
77
+ OutputProxy.new( :audio, @name, @output_index, @name ).inputs.should == []
78
+ end
79
+
80
+ it "should not be added to synthdef" do
81
+ Ugen.should_not_receive( :synthdef )
82
+ OutputProxy.new( :audio, @name, @output_index, @name )
83
+ end
84
+ end
85
+
86
+
data/spec/node_spec.rb ADDED
@@ -0,0 +1,112 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+
3
+ require "scruby/core_ext/typed_array"
4
+ require "scruby/node"
5
+ require "scruby/bus"
6
+
7
+ require 'scruby/server'
8
+ require File.join( File.expand_path(File.dirname(__FILE__)), "server")
9
+
10
+ include Scruby
11
+
12
+ describe Node do
13
+ before :all do
14
+ @server = Server.new
15
+ end
16
+
17
+ before do
18
+ Node.reset!
19
+ Server.stub!(:all).and_return([@server])
20
+ end
21
+
22
+ it "should have incremental uniq id" do
23
+ 10.times do |i|
24
+ Node.new.id.should == 2001 + i
25
+ end
26
+ end
27
+
28
+ it "should reset" do
29
+ Node.new.id.should == 2001
30
+ end
31
+
32
+ describe 'instantiation' do
33
+ it "should not accept non servers" do
34
+ lambda{ Node.new(1,2) }.should raise_error(TypeError)
35
+ lambda{ Node.new([1,2]) }.should raise_error(TypeError)
36
+ end
37
+
38
+ it "should accept a server and have a TypedArray of Servers" do
39
+ n = Node.new @server
40
+ n.servers.should == [@server]
41
+ end
42
+
43
+ it "should have default servers if no server is passed" do
44
+ n = Node.new
45
+ n.servers.should == [@server]
46
+ end
47
+ end
48
+
49
+ describe 'Server interaction' do
50
+ before :all do
51
+ @server = Server.new
52
+ @server.boot
53
+ @server.send "/dumpOSC", 3
54
+ sleep 0.05
55
+ end
56
+
57
+ after :all do
58
+ @server.quit
59
+ end
60
+
61
+ before do
62
+ @node = Node.new @server
63
+ end
64
+
65
+ it "should send free" do
66
+ @node.free
67
+ @node.should_not be_running
68
+ @node.group.should be_nil
69
+ @node.should_not be_playing
70
+ sleep 0.05
71
+ @server.output.should =~ %r{\[ "/n_free", #{ @node.id } \]}
72
+ end
73
+
74
+ it "should send run" do
75
+ @node.run
76
+ sleep 0.05
77
+ @server.output.should =~ %r{\[ "/n_run", #{ @node.id }, 1 \]}
78
+ @node.run false
79
+ sleep 0.05
80
+ @server.output.should =~ %r{\[ "/n_run", #{ @node.id }, 0 \]}
81
+ end
82
+
83
+ it "should send run" do
84
+ @node.run
85
+ sleep 0.05
86
+ @server.output.should =~ %r{\[ "/n_run", #{ @node.id }, 1 \]}
87
+ @node.run false
88
+ sleep 0.05
89
+ @server.output.should =~ %r{\[ "/n_run", #{ @node.id }, 0 \]}
90
+ end
91
+
92
+ describe 'map' do
93
+ it "should just accept instances of Bus" do
94
+ b1 = mock 'Bus', :index => 1, :channels => 1, :rate => :audio
95
+ b1.should_receive(:kind_of?).and_return(false)
96
+ lambda { @node.map :freq1 => b1 }.should raise_error(ArgumentError)
97
+ end
98
+
99
+ it "should send map" do
100
+ b1 = mock 'Bus', :index => 1, :channels => 1, :rate => :control
101
+ b1.should_receive(:kind_of?).and_return(true)
102
+ b2 = mock 'Bus', :index => 2, :channels => 2, :rate => :audio
103
+ b2.should_receive(:kind_of?).and_return(true)
104
+ @node.map( :freq1 => b1, :freq2 => b2 ).should be_instance_of(Node)
105
+ sleep 0.05
106
+ @server.output.should =~ %r{\[ \"#bundle\", 1, \n \[ \"/n_mapn\", #{ @node.id }, \"freq1\", #{ b1.index }, 1 \],\n \[ \"/n_mapan\", #{ @node.id }, \"freq2\", #{ b2.index }, 2 \]\n\]}
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ end
@@ -0,0 +1,196 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper"
2
+
3
+
4
+ require "scruby/control_name"
5
+ require "scruby/env"
6
+ require "scruby/ugens/ugen"
7
+ require "scruby/ugens/ugen_operations"
8
+ require "scruby/ugens/operation_ugens"
9
+ require "scruby/core_ext/delegator_array"
10
+
11
+ include Scruby
12
+ include Ugens
13
+
14
+ class MockUgen < Ugen
15
+ class << self; public :new; end
16
+ end
17
+
18
+ describe UnaryOpUGen do
19
+ ::RATES = :scalar, :demand, :control, :audio
20
+
21
+ before do
22
+ @scalar = MockUgen.new :scalar
23
+ @demand = MockUgen.new :demand
24
+ @control = MockUgen.new :control
25
+ @audio = MockUgen.new :audio
26
+ end
27
+
28
+ describe UnaryOpUGen do
29
+
30
+ before do
31
+ @op = UnaryOpUGen.new( :neg, @audio )
32
+ end
33
+
34
+ it "should return special index" do
35
+ UnaryOpUGen.new( :neg, @audio ).special_index.should == 0
36
+ UnaryOpUGen.new( :bitNot, @audio ).special_index.should == 4
37
+ UnaryOpUGen.new( :abs, @audio ).special_index.should == 5
38
+ UnaryOpUGen.new( :asFloat, @audio ).special_index.should == 6
39
+ end
40
+
41
+ it "should accept just one input" do
42
+ lambda{ UnaryOpUGen.new(:neg, @audio, @demand) }.should raise_error( ArgumentError )
43
+ end
44
+
45
+ it "should just accept defined operators" # do
46
+ # lambda{ UnaryOpUGen.new(:not_operator, @audio) }.should raise_error( ArgumentError )
47
+ # end
48
+
49
+ it "should get max rate" do
50
+ UnaryOpUGen.send(:get_rate, @scalar, @demand ).should == :demand
51
+ UnaryOpUGen.send(:get_rate, @scalar, @demand, @audio ).should == :audio
52
+ UnaryOpUGen.send(:get_rate, @scalar, [@demand, [@control, @audio]] ).should == :audio
53
+ end
54
+
55
+ it do
56
+ UnaryOpUGen.new(:neg, @audio).should be_instance_of(UnaryOpUGen)
57
+ end
58
+
59
+ it "should set rate" do
60
+ UnaryOpUGen.new(:neg, @audio).rate.should == :audio
61
+ UnaryOpUGen.new(:neg, @scalar).rate.should == :scalar
62
+ end
63
+
64
+ it "should set operator" do
65
+ UnaryOpUGen.new(:neg, @audio).operator.should == :neg
66
+ end
67
+ end
68
+
69
+ describe BinaryOpUGen do
70
+
71
+ before do
72
+ @arg_array = [@audio, [@scalar, @audio, [@demand, [@control, @demand]]] ]
73
+ @op_arr = BinaryOpUGen.new(:+, @audio, @arg_array )
74
+ end
75
+
76
+ it "should return special index" do
77
+ BinaryOpUGen.new( :+, @audio, @audio ).special_index.should == 0
78
+ BinaryOpUGen.new( :-, @audio, @audio ).special_index.should == 1
79
+ BinaryOpUGen.new( :*, @audio, @audio ).special_index.should == 2
80
+ BinaryOpUGen.new( :/, @audio, @audio ).special_index.should == 4
81
+ end
82
+
83
+ it "should accept exactly two inputs" do
84
+ lambda{ BinaryOpUGen.new(:+, @audio) }.should raise_error( ArgumentError )
85
+ lambda{ BinaryOpUGen.new(:+, @audio, @demand, @demand) }.should raise_error( ArgumentError )
86
+ end
87
+
88
+ it "should have correct inputs and operator when two inputs" do
89
+ arr = BinaryOpUGen.new( :+, @audio, @demand )
90
+ arr.inputs.should == [@audio, @demand]
91
+ arr.operator.should == :+
92
+ arr.rate.should == :audio
93
+ end
94
+
95
+ it "should accept array as input" do
96
+ BinaryOpUGen.new(:+, @audio, [@audio, @scalar] ).should be_instance_of(DelegatorArray)
97
+ end
98
+
99
+ it "should return an array of UnaryOpUGens" do
100
+ @op_arr.flatten.map { |op| op.should be_instance_of(BinaryOpUGen) }
101
+ end
102
+
103
+ it "should set rate for all operations" do
104
+ @op_arr.flatten.map { |op| op.rate.should eql(:audio) }
105
+ end
106
+
107
+ it "should set operator for all operations" do
108
+ @op_arr.flatten.map { |op| op.operator.should eql(:+) }
109
+ end
110
+
111
+ it "should set correct inputs when provided an array" do
112
+ arr = BinaryOpUGen.new(:+, @control, [@audio, @scalar] )
113
+ arr.first.inputs.should == [@control, @audio]
114
+ arr.last.inputs.should == [@control, @scalar]
115
+ end
116
+
117
+ it "should create the correct number of operations" do
118
+ @op_arr.flatten.size.should eql( @arg_array.flatten.size )
119
+ end
120
+
121
+ it "should replicate the array passed" do
122
+ last = lambda do |i|
123
+ if i.instance_of?( BinaryOpUGen)
124
+ i.inputs.first.should == @audio
125
+ i.inputs.last
126
+ else
127
+ i.map{ |e| last.call(e) }
128
+ end
129
+ end
130
+ last.call(@op_arr).should == @arg_array
131
+ end
132
+
133
+ it "should accept numbers as inputs" do
134
+ arr = BinaryOpUGen.new(:+, @control, [100, 200.0] )
135
+ arr.first.inputs.should == [@control, 100]
136
+ arr.last.inputs.should == [@control, 200.0]
137
+ BinaryOpUGen.new(:+, 100, @control ).inputs.should == [100, @control]
138
+ end
139
+
140
+ it "should accept array as input" do
141
+ arr = BinaryOpUGen.new(:+, [@audio, @scalar], @control )
142
+ arr.first.inputs.should == [@audio, @control]
143
+ arr.last.inputs.should == [@scalar, @control]
144
+ end
145
+
146
+ it "should accept numeric arg as first arg" do
147
+ arr = BinaryOpUGen.new(:+, 1, @control )
148
+ arr.inputs.should == [1, @control]
149
+ end
150
+ end
151
+
152
+ describe MulAdd do
153
+ it do
154
+ MulAdd.new( @audio, 0.5, 0.5 ).should be_instance_of(MulAdd)
155
+ end
156
+
157
+ it do
158
+ MulAdd.new( @audio, 0.5, 0.5 ).rate.should == :audio
159
+ end
160
+
161
+ it do
162
+ MulAdd.new( @audio, 0.5, 0.5 ).inputs.should == [@audio, 0.5, 0.5]
163
+ end
164
+
165
+ it "should not be instance of MulAdd" do
166
+ unary_op = mock 'neg'
167
+ mult = mock 'mult'
168
+ minus = mock 'minus'
169
+ plus = mock 'plus'
170
+
171
+ @audio.should_receive( :neg ).and_return( unary_op )
172
+ @audio.should_receive( :* ).and_return( mult )
173
+ add = mock( '0.5', :- => minus, :zero? => false )
174
+ @audio.should_receive( :+ ).and_return( plus )
175
+
176
+ MulAdd.new( @audio, 0, 0.5 ).should be_instance_of( Float )
177
+ MulAdd.new( @audio, 1, 0 ).should == @audio
178
+ MulAdd.new( @audio, -1, 0 ).should == unary_op
179
+ MulAdd.new( @audio, 0.5, 0 ).should == mult
180
+ MulAdd.new( @audio, -1, add ).should == minus
181
+ MulAdd.new( @audio, 1, 0.5 ).should == plus
182
+ end
183
+
184
+ it "should accept ugens" do
185
+ MulAdd.new( @audio, @audio, 1 ).should be_instance_of(MulAdd)
186
+ MulAdd.new( @audio, @audio, @scalar ).should be_instance_of(MulAdd)
187
+
188
+ bin_op_ugen = mock 'binary op ugen'
189
+ @audio.stub!( :* ).and_return bin_op_ugen
190
+ MulAdd.new( @audio, @audio, 0 ).should == bin_op_ugen
191
+ end
192
+
193
+ end
194
+
195
+ end
196
+