Module: Scruby::Ugens

Defined in:
lib/scruby/ugens/ugen.rb,
lib/scruby/ugens/ugens.rb,
lib/scruby/ugens/demand.rb,
lib/scruby/ugens/in_out.rb,
lib/scruby/ugens/panner.rb,
lib/scruby/ugens/env_gen.rb,
lib/scruby/ugens/multi_out.rb,
lib/scruby/ugens/disk_in_out.rb,
lib/scruby/ugens/operation_ugens.rb,
lib/scruby/ugens/ugen_operations.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

.define_ugen(name, rates) ⇒ Object

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
      "        def new \#{ args.collect{ |a, v| \"\#{ a } = \#{ v.inspect }\"  }.join(', ') }\n          super \#{ args.unshift([rate.inspect]).collect{ |a| a.first }.join(', ') }\n        end\n      RUBY_EVAL\n    else\n      args ||= []\n      args.push [:mul, 1], [:add, 0]\n      args.uniq!\n      assigns = []\n      args.each_with_index do |arg, index|\n        key, val = arg\n        assigns << %{  \n          \#{ key } = opts[:\#{ key }] || args[\#{ index }] || \#{ val }\n          raise( ArgumentError.new(\"`\#{ key }` value must be provided\") ) unless \#{ key }\n        }\n      end\n\n      new_args = [\":\#{ rate }\"] + args[0...-2].collect{ |a| a.first }\n      <<-RUBY_EVAL\n      def \#{ rate_name[rate] } *args\n        raise ArgumentError.new(\"wrong number of arguments (\\\#{ args } for \#{ args.size })\") if args.size > \#{args.size}\n        opts = args.last.kind_of?( Hash ) ? args.pop : {}\n        \#{ assigns.join(\"\\n\") }\n        new( \#{ new_args.join(', ') } ).muladd( mul, add )\n      end\n\n      def params\n        @params\n      end\n      RUBY_EVAL\n    end\n  end.join(\"\\n\")\n\n  self.class_eval <<-RUBY_EVAL\n  class \#{ name } < Ugen\n    @params = \#{ rates.inspect }\n    class << self\n      \#{ methods }\n    end\n  end\n  RUBY_EVAL\n  # # TODO: Load from ~/Ugens directory\nend\n"