maca-Scruby 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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,44 @@
1
+ module Scruby
2
+ module Audio
3
+ module Ugens
4
+ module UgenOperations
5
+ operation_indices = YAML::load( File.open( "#{SCRUBY_DIR}/audio/ugens/operation_indices.yaml" ) )
6
+ UNARY = operation_indices['unary']
7
+ BINARY = operation_indices['binary']
8
+ OP_SYMBOLS = { :+ => :plus, :- => :minus, :* => :mult, :/ => :div2, :<= => :less_than_or_eql, :>= => :more_than_or_eql }
9
+
10
+ def valid_ugen_input?
11
+ true
12
+ end
13
+
14
+ def self.included( klass )
15
+ klass.send( :include, BinaryOperations )
16
+ begin; klass.send( :include, UnaryOperators ) if klass.new.ugen?; rescue; end
17
+
18
+ BINARY.each_key do |operator|
19
+ override = OP_SYMBOLS[operator] || operator #can't name a method ugen_+ so use OP_SYMBOLS hash to get a 'safe' name
20
+ begin; klass.send :alias_method, "original_#{override}", operator; rescue; end #if there is an original operator method make an alias with the prefix 'original' so it may be called latter
21
+ klass.send :alias_method, operator, "ugen_#{override}" #alias the newly added operator method with the name of the operator( +, -, mod, etc...)
22
+ end
23
+ end
24
+
25
+ module BinaryOperations
26
+ BINARY.each_key do |op|
27
+ method_name = OP_SYMBOLS[op] || op #get a 'safe' method name for the method to add
28
+ eval "def ugen_#{method_name}( input )
29
+ return BinaryOpUGen.new(:#{op}, self, input) if input.ugen?
30
+ return self.original_#{method_name}( input ) if self.respond_to?( :original_#{method_name} )
31
+ raise ArgumentError.new( %(Expected \#\{input\} to be an Ugen) )
32
+ end"
33
+ end
34
+ end
35
+
36
+ module UnaryOperators
37
+ UNARY.each_key do |op|
38
+ eval "def #{op}; UnaryOpUgen.new(:#{op}, self); end"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module Scruby
2
+ module Audio
3
+ module Ugens
4
+ ugen_defs = YAML::load( File.open( "#{SCRUBY_DIR}/audio/ugens/ugen_defs.yaml" ) )
5
+ puts 'Loading ugen definitions'
6
+
7
+ def self.define_ugen(name, rates)
8
+ rate_name = {:audio => :ar, :control => :kr, :scalar => :ir, :demand => :new}
9
+ rates.delete_if{ |key, value| key == :demand } #I don't know what to do with these
10
+
11
+ methods = rates.collect{ |r| ":#{rate_name[r.first]}" }.join(', ')
12
+
13
+ klass = "class #{name} < Ugen\nclass << self\n" +
14
+ rates.collect do |r|
15
+ new_args = ( [r.first] + r.last.collect{|a|a.first} ).join(', ')
16
+ args = (r.last + [[:mul,1],[:add,0]]).collect{ |a| a.compact.join(' = ')}.join(', ')
17
+ " def #{rate_name[r.first]}(#{args})\n" +
18
+ " new(:#{new_args}).muladd(mul, add)" +
19
+ "\n end"
20
+ end.join("\n") + "\nnamed_args_for #{methods}\nend\nend\n"
21
+
22
+ self.class_eval klass
23
+ end
24
+
25
+ ugen_defs.each_pair do |key, value|
26
+ self.define_ugen(key, value)
27
+ print '.'
28
+ $stdout.flush
29
+ end
30
+ puts
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ module Scruby
2
+ module Control
3
+ class Metro
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,109 @@
1
+
2
+ class Object
3
+ def to_array
4
+ [*self]
5
+ end
6
+
7
+ def ugen?
8
+ false
9
+ end
10
+
11
+ def valid_ugen_input?
12
+ false
13
+ end
14
+ end
15
+
16
+ class Numeric
17
+ def rate
18
+ :scalar
19
+ end
20
+
21
+ def max( other )
22
+ self > other ? self : other
23
+ end
24
+
25
+ def min( other )
26
+ self < other ? self : other
27
+ end
28
+ end
29
+
30
+ class Numeric
31
+ private
32
+ def collect_constants #:nodoc:
33
+ self
34
+ end
35
+
36
+ def input_specs( synthdef )
37
+ [-1, synthdef.constants.index(self)]
38
+ end
39
+ end
40
+
41
+ class Fixnum
42
+ include Scruby::Audio::Ugens::UgenOperations
43
+ end
44
+
45
+ class Float
46
+ include Scruby::Audio::Ugens::UgenOperations
47
+ end
48
+
49
+ class Array
50
+ include Scruby::Audio::Ugens::UgenOperations
51
+
52
+ #collect with index
53
+ def collect_with_index
54
+ indices = (0...self.size).map
55
+ self.zip( indices ).collect{ |element_with_index| yield( element_with_index.first, element_with_index.last ) }
56
+ end
57
+
58
+ def wrap_to( size )
59
+ return self if size == self.size
60
+ self.dup.wrap_to!( size )
61
+ end
62
+
63
+ def wrap_to!( size )
64
+ return nil if size == self.size
65
+ original_size = self.size
66
+ size.times { |i| self[ i ] = self[ i % original_size ] }
67
+ self
68
+ end
69
+
70
+ def wrap_and_zip( *args )
71
+ max = args.map{ |a| instance_of?(Array) ? a.size : 0 }.max.max( self.size )
72
+ args = args.collect{ |a| a.to_array.wrap_to( max ) }
73
+ self.wrap_to( max ).zip( *args )
74
+ end
75
+
76
+ def to_array
77
+ self
78
+ end
79
+
80
+ def encode_floats
81
+ [self.size].pack('n') + self.pack('g*')
82
+ end
83
+
84
+ def muladd( mul, add )
85
+ self.collect{ |u| MulAdd.new( u, mul, add ) }
86
+ end
87
+
88
+ private
89
+ def collect_constants #:nodoc:
90
+ self.collect{ |e| e.send( :collect_constants ) }
91
+ end
92
+ end
93
+
94
+ class Proc
95
+ def argument_names
96
+ case self.arity
97
+ when -1..0: []
98
+ when 1: self.to_sexp.assoc( :dasgn_curr )[1].to_array
99
+ else self.to_sexp[2][1][1..-1].collect{ |arg| arg[1] }
100
+ end
101
+ end
102
+ end
103
+
104
+ class String
105
+ def encode
106
+ [self.size & 255].pack('C*') + self[0..255]
107
+ end
108
+ end
109
+
@@ -0,0 +1,64 @@
1
+ class TypedArray < Array
2
+
3
+ attr_reader :type
4
+
5
+ def initialize( type, elements = [] )
6
+ @type = type.instance_of?(Class) ? type : type.class
7
+ check_array_passed( elements )
8
+ check_types_for_array( elements )
9
+ super( elements )
10
+ end
11
+
12
+ alias :old_plus :+
13
+ def +( array )
14
+ TypedArray.new( @type, self.old_plus( array ) )
15
+ end
16
+
17
+ def concat( array )
18
+ check_array_passed( array )
19
+ check_types_for_array( array )
20
+ super
21
+ end
22
+
23
+ def <<(e)
24
+ check_type_for_obj(e)
25
+ super
26
+ end
27
+
28
+ def []=(index, e)
29
+ check_type_for_obj(e)
30
+ super
31
+ end
32
+
33
+ def push(e)
34
+ check_type_for_obj(e)
35
+ super
36
+ end
37
+
38
+ def flatten
39
+ self
40
+ end
41
+
42
+ def compact
43
+ self
44
+ end
45
+
46
+ def flatten!
47
+ end
48
+
49
+ def compact!
50
+ end
51
+
52
+ def check_array_passed(obj)
53
+ raise TypeError.new( "#{obj} is not Array" ) unless obj.instance_of?(Array)
54
+ end
55
+
56
+ def check_types_for_array( array ) #:nodoc:
57
+ raise TypeError.new("All elements of #{array} should be instance of #{@type}") unless array.reject{ |e| e.instance_of?(@type) }.empty?
58
+ end
59
+
60
+ def check_type_for_obj( obj ) #:nodoc:
61
+ raise TypeError.new("#{obj} is not instance of #{@type}") unless obj.instance_of?(@type)
62
+ end
63
+
64
+ end
@@ -0,0 +1,25 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)), '..', "helper")
2
+
3
+ require 'named_arguments'
4
+ require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
5
+ require "#{SCRUBY_DIR}/audio/ugens/ugen"
6
+ require "#{SCRUBY_DIR}/extensions"
7
+ require "#{SCRUBY_DIR}/audio/env"
8
+ require "#{SCRUBY_DIR}/audio/ugens/env_gen"
9
+
10
+ include Scruby
11
+ include Audio
12
+ include Ugens
13
+
14
+
15
+ describe EnvGen do
16
+
17
+ it "should have correct inputs" do
18
+ envgen = EnvGen.kr( Env.adsr )
19
+ envgen.rate.should == :control
20
+ envgen.inputs.should == [ 1, 1, 0, 1, 0, 0, 3, 2, -99, 1, 0.01, 5, -4, 0.5, 0.3, 5, -4, 0, 1, 5, -4 ].collect{ |i| i.to_f }
21
+ end
22
+
23
+
24
+
25
+ end
@@ -0,0 +1,107 @@
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 "#{SCRUBY_DIR}/audio/ugens/ugen"
6
+ require "#{SCRUBY_DIR}/audio/ugens/multi_out_ugens"
7
+ require "#{SCRUBY_DIR}/audio/ugens/in_out"
8
+
9
+
10
+ require 'named_arguments'
11
+
12
+ include Scruby
13
+ include Audio
14
+ include Ugens
15
+
16
+ class SinOsc < Ugen
17
+ def self.ar( freq=440.0, phase=0.0 ) #not interested in muladd
18
+ new(:audio, freq, phase)
19
+ end
20
+ end
21
+
22
+ describe In do
23
+
24
+ before do
25
+ @sdef = mock( 'ugen', :children => [] )
26
+ Ugen.should_receive( :synthdef ).at_least( :once ).and_return( @sdef )
27
+
28
+ @proxy = mock('output proxy', :valid_ugen_input? => true )
29
+ @proxies = (1..10).map{ @proxy }
30
+ OutputProxy.stub!(:new).and_return( @proxy )
31
+
32
+ @ar = In.ar( 3 )
33
+ end
34
+
35
+ it "respond to #kr and #ar "do
36
+ In.should respond_to(:kr)
37
+ In.should respond_to(:ar)
38
+ end
39
+
40
+ it "should spec #ar" do
41
+ @ar.should be_instance_of( Array )
42
+ @ar.should have(1).proxy
43
+ @ar.first.should == @proxy
44
+ end
45
+
46
+ it "should have bus as input" do
47
+ @sdef.children.first.inputs.should == [3]
48
+ end
49
+
50
+ it "should have ten channels" do
51
+ In.ar(0, 10).should == @proxies
52
+ end
53
+
54
+ it "should describe passing arrays to initialize"
55
+
56
+ end
57
+
58
+
59
+ describe Out do
60
+
61
+ before do
62
+ @sdef = mock( 'sdef', :children => [], :constants => [400, 0] )
63
+ Ugen.should_receive( :synthdef ).at_least( :once ).and_return( @sdef )
64
+
65
+ end
66
+
67
+ it "should accept one ugen" do
68
+ @ugen1 = Ugen.new( :audio )
69
+
70
+ Out.kr( 1, @ugen1 ).should == 0.0
71
+
72
+ @sdef.children.should have(2).ugens
73
+
74
+ out = @sdef.children.last
75
+ out.rate.should == :control
76
+ out.inputs.should == [1, @ugen1]
77
+ out.channels.should == []
78
+ end
79
+
80
+ it "should accept several inputs" do
81
+ @ugen1 = Ugen.new( :audio )
82
+ @ugen2 = Ugen.new( :audio )
83
+ @ugen3 = Ugen.new( :audio )
84
+
85
+ Out.kr( 1, @ugen1, @ugen2, @ugen3 )
86
+ @sdef.children.should have(4).ugens
87
+
88
+ out = @sdef.children.last
89
+ out.inputs.should == [1, @ugen1, @ugen2, @ugen3]
90
+ end
91
+
92
+ it "should accept several inputs from array" do
93
+ @ugen1 = Ugen.new( :audio )
94
+ @ugen2 = Ugen.new( :audio )
95
+ @ugen3 = Ugen.new( :audio )
96
+
97
+ Out.kr( 1, [@ugen1, @ugen2, @ugen3] )
98
+ @sdef.children.should have(4).ugens
99
+
100
+ out = @sdef.children.last
101
+ out.inputs.should == [1, @ugen1, @ugen2, @ugen3]
102
+ end
103
+
104
+ it "should validate rate"
105
+ it "should substitute zero with silence"
106
+ it "should spec passing array on init"
107
+ end
@@ -0,0 +1,106 @@
1
+ require File.join( File.expand_path(File.dirname(__FILE__)), '..',"helper")
2
+ require "named_arguments"
3
+ require 'osc'
4
+
5
+ require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
6
+ require "#{SCRUBY_DIR}/audio/ugens/ugen"
7
+ require "#{SCRUBY_DIR}/audio/ugens/multi_out_ugens"
8
+ require "#{SCRUBY_DIR}/audio/ugens/in_out"
9
+
10
+ require "#{SCRUBY_DIR}/audio/ugens/operation_ugens"
11
+ require "#{SCRUBY_DIR}/audio/ugens/ugen"
12
+
13
+ require "#{SCRUBY_DIR}/audio/ugens/ugens"
14
+ require "#{SCRUBY_DIR}/audio/control_name"
15
+ require "#{SCRUBY_DIR}/audio/synthdef"
16
+ require "#{SCRUBY_DIR}/extensions"
17
+
18
+ require "#{SCRUBY_DIR}/audio/server"
19
+
20
+ require "#{SCRUBY_DIR}/audio/env"
21
+ require "#{SCRUBY_DIR}/audio/ugens/env_gen"
22
+
23
+ include Scruby
24
+ include Audio
25
+ include Ugens
26
+ include OperationUgens
27
+
28
+ describe "synthdef examples" do
29
+
30
+ before :all do
31
+ @sdef = SynthDef.new(:hola){ |a, b| SinOsc.kr( a ) + SinOsc.kr( b ) }
32
+ @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*')
33
+ end
34
+
35
+ it "should have correct children" do
36
+ @sdef.children[0].should be_instance_of( Control )
37
+ @sdef.children[1].should be_instance_of( SinOsc )
38
+ @sdef.children[2].should be_instance_of( SinOsc )
39
+ @sdef.children[3].should be_instance_of( BinaryOpUGen )
40
+ end
41
+
42
+ it "should encode with control" do
43
+ @sdef.encode.should == @expected
44
+ end
45
+
46
+ it "should encode with ops" do
47
+ 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*')
48
+ SynthDef.new(:help){ (SinOsc.ar() + SinOsc.ar()) * SinOsc.ar() }.encode.should == expected
49
+ end
50
+
51
+ it "should encode with out" do
52
+ sdef = SynthDef.new(:out){ Out.ar(0, SinOsc.ar) }
53
+ sdef.children.should have(2).children
54
+
55
+ sdef.children[0].should be_instance_of( SinOsc )
56
+ sdef.children[1].should be_instance_of( Out )
57
+
58
+ sdef.constants.should == [ 440, 0 ]
59
+ sdef.children[1].channels.should == []
60
+
61
+ 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*')
62
+ sdef.encode.should == expected
63
+ end
64
+
65
+ it "should encode another with out" do
66
+ sdef = SynthDef.new(:out){ sig = SinOsc.ar(100, 200) * SinOsc.ar(200); Out.ar(0, sig) }
67
+ 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*')
68
+ end
69
+
70
+ it "should encode out with two channels" do
71
+ sdef = SynthDef.new( :out ){ sig = SinOsc.ar(100, [200, 200]) * SinOsc.ar(200); Out.ar(0, sig) }
72
+ 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*')
73
+ sdef.encode.should == expected
74
+ end
75
+
76
+ it "should encode out with multidimensional array" do
77
+ sdef = SynthDef.new( :out ){ sig = SinOsc.ar(100, [200,[100, 100]]) * SinOsc.ar(200); Out.ar(0, sig) }
78
+
79
+ child = sdef.children
80
+ child[0..3].map { |u| u.should be_instance_of(SinOsc) }
81
+ child[4].should be_instance_of(BinaryOpUGen)
82
+ child[5].should be_instance_of(BinaryOpUGen)
83
+ child[6].should be_instance_of(BinaryOpUGen)
84
+ child[7].should be_instance_of(Out)
85
+ child[8].should be_instance_of(Out)
86
+ #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
87
+ sdef.encode.should have(261).chars
88
+ end
89
+
90
+ it "should encode 'complex' sdef" do
91
+ sdef = SynthDef.new( :am ) do |gate, portadora, moduladora, amp|
92
+ modulacion=SinOsc.kr(moduladora,0,0.5,0.5)
93
+ sig=SinOsc.ar(portadora,0,modulacion)
94
+ env=EnvGen.kr(Env.asr(2,1,2),gate, :doneAction => 2)
95
+ Out.ar(0,sig*env);
96
+ end
97
+ sdef.children.should have(8).children
98
+ sdef.constants.should == [0, 0.5, 1, 2, -99, 5, -4]
99
+
100
+ 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*')
101
+ sdef.encode.should == expected
102
+ end
103
+
104
+
105
+ end
106
+