scruby 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +53 -0
- data/README.rdoc +65 -0
- data/Rakefile +10 -0
- data/TODO.markdown +3 -0
- data/examples/example.rb +73 -0
- data/lib/scruby/buffer.rb +153 -0
- data/lib/scruby/bus.rb +67 -0
- data/lib/scruby/control_name.rb +29 -0
- data/lib/scruby/core_ext/array.rb +44 -0
- data/lib/scruby/core_ext/delegator_array.rb +44 -0
- data/lib/scruby/core_ext/fixnum.rb +8 -0
- data/lib/scruby/core_ext/numeric.rb +25 -0
- data/lib/scruby/core_ext/object.rb +23 -0
- data/lib/scruby/core_ext/proc.rb +11 -0
- data/lib/scruby/core_ext/string.rb +5 -0
- data/lib/scruby/core_ext/symbol.rb +5 -0
- data/lib/scruby/core_ext/typed_array.rb +54 -0
- data/lib/scruby/env.rb +93 -0
- data/lib/scruby/group.rb +24 -0
- data/lib/scruby/node.rb +102 -0
- data/lib/scruby/server.rb +182 -0
- data/lib/scruby/synth.rb +50 -0
- data/lib/scruby/synthdef.rb +109 -0
- data/lib/scruby/ticker.rb +92 -0
- data/lib/scruby/ugens/buffer_read_write.rb +98 -0
- data/lib/scruby/ugens/demand.rb +9 -0
- data/lib/scruby/ugens/disk_in_out.rb +33 -0
- data/lib/scruby/ugens/env_gen.rb +38 -0
- data/lib/scruby/ugens/in_out.rb +46 -0
- data/lib/scruby/ugens/multi_out.rb +53 -0
- data/lib/scruby/ugens/operation_indices.yaml +92 -0
- data/lib/scruby/ugens/operation_ugens.rb +63 -0
- data/lib/scruby/ugens/panner.rb +137 -0
- data/lib/scruby/ugens/ugen.rb +173 -0
- data/lib/scruby/ugens/ugen_defs.yaml +3123 -0
- data/lib/scruby/ugens/ugen_operations.rb +57 -0
- data/lib/scruby/ugens/ugens.rb +95 -0
- data/lib/scruby/version.rb +3 -0
- data/lib/scruby.rb +65 -0
- data/scruby.gemspec +27 -0
- data/spec/buffer_read_write_spec.rb +333 -0
- data/spec/buffer_spec.rb +199 -0
- data/spec/bus_spec.rb +184 -0
- data/spec/core_ext/core_ext_spec.rb +120 -0
- data/spec/core_ext/delegator_array_spec.rb +144 -0
- data/spec/core_ext/typed_array_spec.rb +95 -0
- data/spec/demand_spec.rb +81 -0
- data/spec/disk_in_out_spec.rb +138 -0
- data/spec/env_gen_spec.rb +23 -0
- data/spec/env_spec.rb +73 -0
- data/spec/group_spec.rb +71 -0
- data/spec/helper.rb +20 -0
- data/spec/in_out_spec.rb +127 -0
- data/spec/integration_spec.rb +88 -0
- data/spec/multiout_ugen_spec.rb +86 -0
- data/spec/node_spec.rb +112 -0
- data/spec/operation_ugens_spec.rb +196 -0
- data/spec/panner_spec.rb +271 -0
- data/spec/server.rb +12 -0
- data/spec/server_spec.rb +198 -0
- data/spec/synth_spec.rb +103 -0
- data/spec/synthdef_spec.rb +267 -0
- data/spec/ugen_operations_spec.rb +100 -0
- data/spec/ugen_spec.rb +356 -0
- data/spec/ugens_spec.rb +65 -0
- metadata +207 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
module Scruby
|
2
|
+
module Ugens
|
3
|
+
# All ugens inherit from this "abstract" class
|
4
|
+
#
|
5
|
+
# == Creation
|
6
|
+
#
|
7
|
+
# Ugens are usually instantiated inside an "ugen graph" or the block passed when creating a SynthDef
|
8
|
+
# using either the ar, kr, ir or new methods wich will determine the rate.
|
9
|
+
# * ar: audio rate
|
10
|
+
# * kr: control rate
|
11
|
+
# * ir: scalar rate
|
12
|
+
# * new: demand rate
|
13
|
+
#
|
14
|
+
# Not all the ugens provide all the rates
|
15
|
+
#
|
16
|
+
# Two ugens inside an ugen graph:
|
17
|
+
# SynthDef.new('simple'){ Out.ar(0, SinOsc.ar) }
|
18
|
+
# # Out and SinOsc are both ugens
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# == Passing arguments when creating
|
22
|
+
#
|
23
|
+
# Usually when instantiating an ugen the arguments can be passed in order:
|
24
|
+
# Pitch.kr(0, 220, 80, ...)
|
25
|
+
#
|
26
|
+
# Or using a hash where the keys are symbols corresponding to the argument name.
|
27
|
+
# Pitch.kr( :initFreq => 220, :execFreq => 300 )
|
28
|
+
#
|
29
|
+
# Or a combination of both ways:
|
30
|
+
# Pitch.kr(0, 220, :execFreq => 300)
|
31
|
+
#
|
32
|
+
# Arguments not passed in either way will resort to default
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# == Defining ugens
|
36
|
+
#
|
37
|
+
# This named arguments functionality is provided for all the default Ugens but can be provided when defining a new Ugen by calling
|
38
|
+
# <tt>#named_arguments_for</tt> passing a symbol with the name of a defined method:
|
39
|
+
#
|
40
|
+
# class Umaguma < Ugen
|
41
|
+
# class << self
|
42
|
+
# def ar(karma = 200, pitch = 20, rate = 200)
|
43
|
+
# ...
|
44
|
+
# end
|
45
|
+
# named_arguments_for :ar
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# For more info and limitations on named arguments check the gem: http://github.com/maca/arguments
|
51
|
+
#
|
52
|
+
# Otherwise usage is pretty the same as in SuperCollider
|
53
|
+
#
|
54
|
+
# TODO: Provide a way of getting the argument names and default values
|
55
|
+
class Ugen
|
56
|
+
attr_reader :inputs, :rate, :index, :special_index, :output_index, :channels
|
57
|
+
|
58
|
+
RATES = :scalar, :trigger, :demand, :control, :audio
|
59
|
+
E_RATES = :scalar, :control, :audio, :demand
|
60
|
+
VALID_INPUTS = Numeric, Array, Ugen, Env, ControlName
|
61
|
+
@@synthdef = nil
|
62
|
+
|
63
|
+
|
64
|
+
def initialize rate, *inputs
|
65
|
+
@rate, @inputs = rate, inputs.compact
|
66
|
+
@special_index ||= 0
|
67
|
+
@output_index ||= 0
|
68
|
+
@channels ||= [1]
|
69
|
+
@index = add_to_synthdef || 0
|
70
|
+
end
|
71
|
+
|
72
|
+
# Instantiate a new MulAdd passing self and the multiplication and addition arguments
|
73
|
+
def muladd mul, add
|
74
|
+
MulAdd.new self, mul, add
|
75
|
+
end
|
76
|
+
|
77
|
+
def encode
|
78
|
+
self.class.to_s.split('::').last.encode + [ E_RATES.index(rate) ].pack('w') +
|
79
|
+
[ inputs.size, channels.size, special_index, collect_input_specs ].flatten.pack('n*') +
|
80
|
+
output_specs.pack('w*')
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def synthdef #:nodoc:
|
85
|
+
@synthdef ||= Ugen.synthdef
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_to_synthdef #:nodoc:
|
89
|
+
(synthdef.children << self).size - 1 if synthdef
|
90
|
+
end
|
91
|
+
|
92
|
+
def collect_constants #:nodoc:
|
93
|
+
@inputs.send( :collect_constants )
|
94
|
+
end
|
95
|
+
|
96
|
+
def input_specs synthdef #:nodoc:
|
97
|
+
[index, output_index]
|
98
|
+
end
|
99
|
+
|
100
|
+
def collect_input_specs #:nodoc:
|
101
|
+
@inputs.collect{ |i| i.send :input_specs, synthdef }
|
102
|
+
end
|
103
|
+
|
104
|
+
def output_specs #:nodoc:
|
105
|
+
[E_RATES.index(rate)]
|
106
|
+
end
|
107
|
+
|
108
|
+
public
|
109
|
+
def == other
|
110
|
+
self.class == other.class and
|
111
|
+
self.rate == other.rate and
|
112
|
+
self.inputs == other.inputs and
|
113
|
+
self.channels == other.channels
|
114
|
+
end
|
115
|
+
|
116
|
+
class << self
|
117
|
+
#:nodoc:
|
118
|
+
private
|
119
|
+
def new rate, *inputs
|
120
|
+
if rate.kind_of? Array
|
121
|
+
rate = RATES.slice rate.collect { |rate| # get the highest rate, raise error if rate is not defined
|
122
|
+
rate = rate.to_sym
|
123
|
+
raise ArgumentError.new( "#{rate} not a defined rate") unless RATES.include? rate
|
124
|
+
RATES.index rate
|
125
|
+
}.max
|
126
|
+
else
|
127
|
+
raise ArgumentError.new( "#{rate} not a defined rate") unless RATES.include? rate.to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
size = 1 # Size of the largest multichannel input (Array)
|
131
|
+
inputs.peel! # First input if input is Array and size is 1
|
132
|
+
inputs.map! do |input|
|
133
|
+
input = input.as_ugen_input if input.respond_to?(:as_ugen_input) # Convert input to prefered form
|
134
|
+
raise ArgumentError.new( "#{ input.inspect } is not a valid ugen input") unless valid_input? input
|
135
|
+
size = input.size if input.size > size if input.kind_of? Array
|
136
|
+
input
|
137
|
+
end
|
138
|
+
|
139
|
+
return super( rate, *inputs.flatten ) unless size > 1 #return an Ugen if no array was passed as an input
|
140
|
+
|
141
|
+
inputs.map! do |input|
|
142
|
+
Array === input ? input.wrap_to!(size) : input = Array.new(size, input)
|
143
|
+
input
|
144
|
+
end
|
145
|
+
output = inputs.transpose
|
146
|
+
output.map! do |new_inputs| new rate, *new_inputs end
|
147
|
+
output.to_da
|
148
|
+
end
|
149
|
+
|
150
|
+
public
|
151
|
+
def valid_input? obj
|
152
|
+
case obj
|
153
|
+
when *VALID_INPUTS then true
|
154
|
+
else false
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def synthdef #:nodoc:
|
159
|
+
@@synthdef
|
160
|
+
end
|
161
|
+
|
162
|
+
def synthdef= synthdef #:nodoc:
|
163
|
+
@@synthdef = synthdef
|
164
|
+
end
|
165
|
+
|
166
|
+
def params
|
167
|
+
{}
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|