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.
- data/README.rdoc +26 -0
- data/Rakefile +10 -0
- data/Scruby.gemspec +36 -0
- data/bin/live_session.rb +12 -0
- data/changes +1 -0
- data/lib/live/session.rb +144 -0
- data/lib/scruby.rb +60 -0
- data/lib/scruby/audio/control_name.rb +29 -0
- data/lib/scruby/audio/env.rb +97 -0
- data/lib/scruby/audio/node.rb +20 -0
- data/lib/scruby/audio/server.rb +112 -0
- data/lib/scruby/audio/synth.rb +15 -0
- data/lib/scruby/audio/synthdef.rb +114 -0
- data/lib/scruby/audio/ugens/env_gen.rb +18 -0
- data/lib/scruby/audio/ugens/in_out.rb +43 -0
- data/lib/scruby/audio/ugens/multi_out_ugens.rb +48 -0
- data/lib/scruby/audio/ugens/operation_indices.yaml +92 -0
- data/lib/scruby/audio/ugens/operation_ugens.rb +64 -0
- data/lib/scruby/audio/ugens/ugen.rb +154 -0
- data/lib/scruby/audio/ugens/ugen_defs.yaml +3421 -0
- data/lib/scruby/audio/ugens/ugen_operations.rb +44 -0
- data/lib/scruby/audio/ugens/ugens.rb +34 -0
- data/lib/scruby/control/metro.rb +6 -0
- data/lib/scruby/extensions.rb +109 -0
- data/lib/scruby/typed_array.rb +64 -0
- data/spec/audio/env_gen_specs.rb +25 -0
- data/spec/audio/in_out_spec.rb +107 -0
- data/spec/audio/integration_spec.rb +106 -0
- data/spec/audio/lib_spec.rb +14 -0
- data/spec/audio/multiout_ugen_spec.rb +112 -0
- data/spec/audio/node_spec.rb +60 -0
- data/spec/audio/operation_ugens_spec.rb +189 -0
- data/spec/audio/server_spec.rb +68 -0
- data/spec/audio/synth_spec.rb +46 -0
- data/spec/audio/synthdef_spec.rb +275 -0
- data/spec/audio/ugen_operations_spec.rb +146 -0
- data/spec/audio/ugen_spec.rb +333 -0
- data/spec/audio/ugens_spec.rb +61 -0
- data/spec/env_spec.rb +64 -0
- data/spec/extensions_spec.rb +133 -0
- data/spec/helper.rb +11 -0
- data/spec/typed_array_spec.rb +95 -0
- 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,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
|
+
|