Module: Scruby::Ugens

Defined in:
lib/scruby/ugens/ugen.rb,
lib/scruby/ugens/ugens.rb,
lib/scruby/ugens/demand.rb,
lib/scruby/ugens/panner.rb,
lib/scruby/ugens/in_out.rb,
lib/scruby/ugens/env_gen.rb,
lib/scruby/ugens/multi_out.rb,
lib/scruby/ugens/disk_in_out.rb,
lib/scruby/ugens/ugen_operations.rb,
lib/scruby/ugens/operation_ugens.rb,
lib/scruby/ugens/buffer_read_write.rb

Defined Under Namespace

Modules: MultiOut, UgenOperations Classes: Balance2, BasicOpUgen, BiPanB2, BinaryOpUGen, BufRd, BufWr, Control, DecodeB2, Demand, DiskIn, DiskOut, EnvGen, In, LinPan2, MulAdd, Out, OutputProxy, Pan2, Pan4, PanAz, PanB, PanB2, PlayBuf, RecordBuf, ReplaceOut, Rotate2, ScopeOut, TGrains, Tap, Ugen, UnaryOpUGen, VDiskIn

Class Method Summary (collapse)

Class Method Details

+ (Object) define_ugen(name, rates)

Default SuperCollider Ugens definitions are stored in the ugen_defs.yml file and are defined as Ruby classes on the fly, the yml format is:

NewUgen: 
  :control: 
  - - :input
    - 
  - - :freq
    - 440
  :audio: 
  - - :input
    - 
  - - :freq
    - 440

To define a Ruby class corresponding to an Ugen name should be passed and a hash of rates, inputs and default values, default values can be nil

Ugens.define_ugen( 'NewUgen', {:control => [[:input, nil], [:freq, 440]], :audio => [[:input, nil], [:freq, 440]]} )

The previous is equivalent as the following ruby code:

class NewUgen < Ugen
  class << self
    def kr( input, freq = 440 )
      new :control, input, freq
    end

    def ar( input, freq = 440)
      new :audio, input, freq
    end
    # Makes possible passing args either in order or as argument hash
    named_arguments_for :ar, :kr
  end
end

In future versions Ugen definitions will be loaded from ~/Ugens or ~/.Ugens directories either as yml files or rb files



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/scruby/ugens/ugens.rb', line 41

def self.define_ugen name, rates
  rate_name = {:audio => :ar, :control => :kr, :scalar => :ir, :demand => :new}

  methods = rates.collect do |rate, args|
    if rate == :demand or rate == :scalar
      <<-RUBY_EVAL
        def new #{ args.collect{ |a, v| "#{ a } = #{ v.inspect }"  }.join(', ') }
          super #{ args.unshift([rate.inspect]).collect{ |a| a.first }.join(', ') }
        end
      RUBY_EVAL
    else
      args ||= []
      args.push [:mul, 1], [:add, 0]
      args.uniq!
      assigns = []
      args.each_with_index do |arg, index|
        key, val = arg
        assigns << %{  
          #{ key } = opts[:#{ key }] || args[#{ index }] || #{ val }
          raise( ArgumentError.new("`#{ key }` value must be provided") ) unless #{ key }
        }
      end

      new_args = [":#{ rate }"] + args[0...-2].collect{ |a| a.first }
      <<-RUBY_EVAL
      def #{ rate_name[rate] } *args
        raise ArgumentError.new("wrong number of arguments (\#{ args } for #{ args.size })") if args.size > #{args.size}
        opts = args.last.kind_of?( Hash ) ? args.pop : {}
        #{ assigns.join("\n") }
        new( #{ new_args.join(', ') } ).muladd( mul, add )
      end

      def params
        @params
      end
      RUBY_EVAL
    end
  end.join("\n")

  self.class_eval <<-RUBY_EVAL
  class #{ name } < Ugen
    @params = #{ rates.inspect }
    class << self
      #{ methods }
    end
  end
  RUBY_EVAL
  # # TODO: Load from ~/Ugens directory
end