Permalink
Browse files

made some methods private, synthdef with ugen graph instantiation now…

… seems complete, need to do integration specs
  • Loading branch information...
1 parent 64f84b4 commit a003f73cba29b1695603916471a228dc7b7cc04c Macario committed Oct 20, 2008
View
Binary file not shown.
View
Binary file not shown.
@@ -1,7 +1,7 @@
module Scruby
module Audio
class SynthDef
- attr_accessor :name, :children, :constants, :control_names
+ attr_reader :name, :children, :constants, :control_names
def initialize( name, options = {}, &block )
@name, @children = name.to_s, []
@@ -11,34 +11,37 @@ def initialize( name, options = {}, &block )
block = block || Proc.new{}
@control_names = collect_control_names( block, values, rates )
+ build_ugen_graph( block, @control_names )
+ @constants = collect_constants( @children )
warn( 'A SynthDef without a block is useless' ) unless block_given?
end
+
+ private
+ attr_writer :name, :children, :constants, :control_names
- def collect_control_names( function, values, rates=[] ) #:nodoc:
+ def collect_control_names( function, values, rates ) #:nodoc:
return [] if (names = function.argument_names).empty?
names.zip( values, rates ).collect_with_index{ |array, index| ControlName.new *(array << index) }
end
- def build_controls( control_names )
-
- arguments = []
-
- control_names_by_rate = [:scalar, :trigger, :control].collect do |rate|
- control_names.select{ |control| control.rate == rate }
- end
-
- for control_names in control_names_by_rate.reject{ |control_names| control_names.empty? }
- end
-
+ def build_controls( control_names ) #:nodoc:
+ # control_names.select{ |c| c.rate == :noncontrol }.sort_by{ |c| c.control_name.index } +
+ [:scalar, :trigger, :control].collect do |rate|
+ same_rate_array = control_names.select{ |control| control.rate == rate }
+ Control.and_proxies_from( same_rate_array ) unless same_rate_array.empty?
+ end.flatten.compact.sort_by{ |proxy| proxy.control_name.index }
end
- def build_ugen_graph( function ) #:nodoc:
+ def build_ugen_graph( function, output_proxies ) #:nodoc:
Ugen.synthdef = self
- function.call
+ function.call output_proxies
Ugen.synthdef = nil
end
+
+ def collect_constants( children ) #:nodoc:
+ children.send( :collect_constants ).flatten.uniq
+ end
end
-
end
end
@@ -2,12 +2,28 @@ module Scruby
module Audio
module Ugens
class OutputProxy
+ attr_reader :source, :control_name, :output_index
+
+ def initialize( source, control_name, index)
+ @source, @control_name, @output_index = source, control_name, index
+ end
end
class MultiOutUgen < Ugen
+ attr_reader :channels, :outputs
+ private
+ attr_writer :channels, :outputs
end
- class Control < MultiOutUgen
+ class Control < MultiOutUgen #:nodoc:
+ def self.and_proxies_from( names )
+ control = Control.new( names.first.rate )
+ control.send :outputs=, names.collect_with_index { |name, index| OutputProxy.new( control, name, index ) }
+ end
+
+ def self.new( rate )
+ control = super( rate, [])
+ end
end
end
end
@@ -2,9 +2,9 @@ module Scruby
module Audio
module Ugens
class Ugen
- attr_accessor :inputs, :rate, :index
+ attr_reader :inputs, :rate, :index
- RATES = [ :scalar, :demand, :control, :audio ]
+ RATES = [ :scalar, :trigger, :demand, :control, :audio ]
@@synthdef = nil
include UgenOperations
@@ -13,31 +13,36 @@ def initialize( rate, *inputs)
@rate, @inputs = rate, inputs
@index = add_to_synthdef
end
-
- def synthdef
- @synthdef ||= self.class.synthdef
- end
-
- def add_to_synthdef #:nodoc:
- (synthdef.children << self).size - 1 if synthdef
+
+ def muladd( mul, add )
+ MulAdd.new( self, mul, add )
end
-
+
def to_s
- "a #{self.class}(#{self.inputs.join(', ')})"
+ "#{self.class} inputs: #{self.inputs.join(', ')}"
end
def ugen?
true
end
- def muladd( mul, add )
- MulAdd.new( self, mul, add )
+ private
+ def synthdef
+ @synthdef ||= self.class.synthdef
+ end
+
+ def add_to_synthdef #:nodoc:
+ (synthdef.children << self).size - 1 if synthdef
+ end
+
+ def collect_constants
+ @inputs.send( :collect_constants )
end
class << self
def new( rate, *inputs ) #:nodoc:
- raise ArgumentError.new( "You have to specify Ugen rate and input(s)" ) if inputs.empty?
raise ArgumentError.new( "#{rate} not a defined rate") unless RATES.include?( rate.to_sym )
+ inputs.each{ |i| raise ArgumentError.new( "#{i} is not a valid ugen input") unless i.valid_ugen_input? }
inputs = *inputs #if args is an array peel off one array skin
inputs = inputs.to_array #may return a non_array object so we turn it into array, does nothing if already array
@@ -6,7 +6,11 @@ module UgenOperations
UNARY = operation_indices['unary']
BINARY = operation_indices['binary']
OP_SYMBOLS = { :+ => :plus, :- => :minus, :* => :mult, :/ => :div2, :<= => :less_than_or_eql, :>= => :more_than_or_eql }
-
+
+ def valid_ugen_input?
+ true
+ end
+
def self.included( klass )
klass.send( :include, BinaryOperations )
begin; klass.send( :include, UnaryOperators ) if klass.new.ugen?; rescue; end
View
@@ -7,6 +7,10 @@ def to_array
def ugen?
false
end
+
+ def valid_ugen_input?
+ false
+ end
end
class Numeric
@@ -15,6 +19,13 @@ def rate
end
end
+class Numeric
+ private
+ def collect_constants #:nodoc:
+ self
+ end
+end
+
class Fixnum
include Scruby::Audio::Ugens::UgenOperations
end
@@ -47,6 +58,11 @@ def wrap_to!( size )
def to_array
self
end
+
+ private
+ def collect_constants #:nodoc:
+ self.collect{ |e| e.send( :collect_constants ) }
+ end
end
class Proc
View
Binary file not shown.
@@ -1,6 +1,6 @@
require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
-require "#{LIB_DIR}/audio/ugen_operations"
+require "#{LIB_DIR}/audio/ugens/ugen_operations"
require "#{LIB_DIR}/extensions"
require "ruby2ruby"
@@ -45,6 +45,7 @@
end
it "should sum with Ugen"
+ it "should collect constants"
end
end
@@ -19,26 +19,15 @@
@sdef = SynthDef.new( :name ) do end
@ugen = Ugen.new( :audio, 100, 200 )
end
-
- it do
- @sdef.should respond_to(:build_ugen_graph)
- end
-
+
it "should return nil #sytnth_def" do
- @ugen.synthdef.should eql(nil)
- end
-
- it "should set @sdef #synthdef=" do
- function = lambda{}
- Ugen.should_receive( :synthdef= ).with( @sdef )
- Ugen.should_receive( :synthdef= ).with( nil )
- @sdef.build_ugen_graph( function )
+ @ugen.send( :synthdef ).should eql(nil)
end
it "should set synthdef to the synth def for ugens instantiated inside ugen graph" do
- function = lambda { Ugen.new( :audio, 100, 200 ).synthdef.should eql( @sdef ) }
- @sdef.build_ugen_graph function
- Ugen.new( :audio, 100, 200 ).synthdef.should eql( nil )
+ function = lambda { Ugen.new( :audio, 100, 200 ).send( :synthdef ).should eql( @sdef ) }
+ @sdef.send :build_ugen_graph, function, []
+ Ugen.new( :audio, 100, 200 ).send( :synthdef ).should eql( nil )
end
@@ -0,0 +1,99 @@
+require File.join(File.expand_path(File.dirname(__FILE__)),"helper")
+
+require "#{LIB_DIR}/audio/ugens/ugen_operations"
+require "#{LIB_DIR}/audio/ugens/ugen"
+require "#{LIB_DIR}/extensions"
+require "#{LIB_DIR}/audio/ugens/multi_out_ugens"
+
+include Scruby
+include Audio
+include Ugens
+
+
+describe MultiOutUgen do
+
+ it "should respond to channels and outputs" do
+ MultiOutUgen.new( :audio, 1 ).should respond_to(:channels)
+ MultiOutUgen.new( :audio, 1 ).should respond_to(:outputs)
+ end
+
+end
+
+describe Control do
+
+
+ before do
+ @control = mock('control', :outputs= => nil)
+ @names = Array.new( rand(7) + 3 ){ |i| mock('name', :rate => :control) }
+ Ugen.synthdef = nil
+ @proxy = mock('proxy', :instance_of_proxy? => true)
+ OutputProxy.stub!( :new ).and_return( @proxy )
+ end
+
+ it "should instantiate just with rate" do
+ Control.new( :audio ).should be_instance_of( Control )
+ end
+
+ it "should have empty inputs" do
+ Control.new( :audio ).inputs.should == []
+ end
+
+ it "should add to synthdef" do
+ sdef = mock('synthdef', :children => [])
+ Ugen.synthdef = sdef
+ Control.new( :audio )
+ sdef.children.should have(1).control
+ end
+
+ it "should have an empty array for inputs" do
+ Control.new( :audio ).inputs.should == []
+ end
+
+ it do
+ Control.should respond_to(:and_proxies_from)
+ end
+
+ it "should return an array" do
+ Control.and_proxies_from( @names ).should be_instance_of(Array)
+ end
+
+ it "should instantiate a control" do
+ Control.should_receive(:new).and_return( @control )
+ Control.and_proxies_from( @names )
+ end
+
+ it "should set rate to the rate of the names of the array" do
+ Control.should_receive(:new).with(:control).and_return( @control )
+ Control.and_proxies_from( @names )
+ end
+
+ it "should instantiate an output proxy for each passed name" do
+ OutputProxy.should_receive( :new ).exactly( @names.size ).times
+ Control.and_proxies_from( @names )
+ end
+
+ it "should instantiate output proxies with the right attributes" do
+ @control = mock('control', :outputs= => nil)
+ Control.stub!( :new ).and_return( @control )
+ @names.collect_with_index { |n, i| OutputProxy.should_receive(:new).with(@control, n, i) }
+ Control.and_proxies_from( @names )
+ end
+
+ it "should return an array of proxies" do
+ Control.and_proxies_from( @names ).each do |proxy|
+ proxy.should be_instance_of_proxy
+ end
+ end
+
+ it "should set outputs" do
+ @control.should_receive( :outputs= )
+ Control.stub!( :new ).and_return( @control )
+ Control.and_proxies_from( @names )
+ end
+end
+
+describe OutputProxy do
+
+
+end
+
@@ -15,10 +15,10 @@
RATES = [ :scalar, :demand, :control, :audio ]
before do
- @scalar = mock( 'ugen', :rate => :scalar )
- @demand = mock( 'ugen', :rate => :demand )
- @control = mock( 'ugen', :rate => :control )
- @audio = mock( 'ugen', :rate => :audio )
+ @scalar = mock( 'ugen', :rate => :scalar, :valid_ugen_input? => true )
+ @demand = mock( 'ugen', :rate => :demand, :valid_ugen_input? => true )
+ @control = mock( 'ugen', :rate => :control, :valid_ugen_input? => true )
+ @audio = mock( 'ugen', :rate => :audio, :valid_ugen_input? => true )
end
describe UnaryOpUgen do
Oops, something went wrong.

0 comments on commit a003f73

Please sign in to comment.