maca-Scruby 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|