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,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
+