maca-Scruby 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/README.rdoc
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
== LICENSE:
|
5
|
+
|
6
|
+
Copyright (c) 2008 Macario Ortega
|
7
|
+
|
8
|
+
This program is free software: you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU General Public License as published by
|
10
|
+
the Free Software Foundation, either version 3 of the License, or
|
11
|
+
(at your option) any later version.
|
12
|
+
|
13
|
+
This program is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU General Public License
|
19
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
== NOTES
|
22
|
+
|
23
|
+
Ruby has operation precendence
|
24
|
+
|
25
|
+
|
26
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('Scruby', '0.0.8') do |p|
|
6
|
+
p.description = "Small client for doing sound synthesis from ruby using the SuperCollider synth, usage is quite similar from SuperCollider."
|
7
|
+
p.url = 'http://github.com/maca/scruby'
|
8
|
+
p.author = "Macario Ortega"
|
9
|
+
p.email = "macarui@gmail.com"
|
10
|
+
end
|
data/Scruby.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{Scruby}
|
5
|
+
s.version = "0.0.8"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Macario Ortega"]
|
9
|
+
s.date = %q{2009-02-05}
|
10
|
+
s.default_executable = %q{live_session.rb}
|
11
|
+
s.description = %q{Small client for doing sound synthesis from ruby using the SuperCollider synth, usage is quite similar from SuperCollider.}
|
12
|
+
s.email = %q{macarui@gmail.com}
|
13
|
+
s.executables = ["live_session.rb"]
|
14
|
+
s.extra_rdoc_files = ["bin/live_session.rb", "lib/live/session.rb", "lib/scruby/audio/control_name.rb", "lib/scruby/audio/env.rb", "lib/scruby/audio/node.rb", "lib/scruby/audio/server.rb", "lib/scruby/audio/synth.rb", "lib/scruby/audio/synthdef.rb", "lib/scruby/audio/ugens/env_gen.rb", "lib/scruby/audio/ugens/in_out.rb", "lib/scruby/audio/ugens/multi_out_ugens.rb", "lib/scruby/audio/ugens/operation_indices.yaml", "lib/scruby/audio/ugens/operation_ugens.rb", "lib/scruby/audio/ugens/ugen.rb", "lib/scruby/audio/ugens/ugen_defs.yaml", "lib/scruby/audio/ugens/ugen_operations.rb", "lib/scruby/audio/ugens/ugens.rb", "lib/scruby/control/metro.rb", "lib/scruby/extensions.rb", "lib/scruby/typed_array.rb", "lib/scruby.rb", "README.rdoc"]
|
15
|
+
s.files = ["bin/live_session.rb", "changes", "lib/live/session.rb", "lib/scruby/audio/control_name.rb", "lib/scruby/audio/env.rb", "lib/scruby/audio/node.rb", "lib/scruby/audio/server.rb", "lib/scruby/audio/synth.rb", "lib/scruby/audio/synthdef.rb", "lib/scruby/audio/ugens/env_gen.rb", "lib/scruby/audio/ugens/in_out.rb", "lib/scruby/audio/ugens/multi_out_ugens.rb", "lib/scruby/audio/ugens/operation_indices.yaml", "lib/scruby/audio/ugens/operation_ugens.rb", "lib/scruby/audio/ugens/ugen.rb", "lib/scruby/audio/ugens/ugen_defs.yaml", "lib/scruby/audio/ugens/ugen_operations.rb", "lib/scruby/audio/ugens/ugens.rb", "lib/scruby/control/metro.rb", "lib/scruby/extensions.rb", "lib/scruby/typed_array.rb", "lib/scruby.rb", "Rakefile", "README.rdoc", "spec/audio/env_gen_specs.rb", "spec/audio/in_out_spec.rb", "spec/audio/integration_spec.rb", "spec/audio/lib_spec.rb", "spec/audio/multiout_ugen_spec.rb", "spec/audio/node_spec.rb", "spec/audio/operation_ugens_spec.rb", "spec/audio/server_spec.rb", "spec/audio/synth_spec.rb", "spec/audio/synthdef_spec.rb", "spec/audio/ugen_operations_spec.rb", "spec/audio/ugen_spec.rb", "spec/audio/ugens_spec.rb", "spec/env_spec.rb", "spec/extensions_spec.rb", "spec/helper.rb", "spec/typed_array_spec.rb", "Manifest", "Scruby.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://github.com/maca/scruby}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Scruby", "--main", "README.rdoc"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{scruby}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{Small client for doing sound synthesis from ruby using the SuperCollider synth, usage is quite similar from SuperCollider.}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 2
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
35
|
+
end
|
36
|
+
end
|
data/bin/live_session.rb
ADDED
data/changes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/lib/live/session.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'highline'
|
4
|
+
require 'parse_tree'
|
5
|
+
require 'ruby2ruby'
|
6
|
+
|
7
|
+
module Kernel
|
8
|
+
alias :l :lambda
|
9
|
+
|
10
|
+
# Calls Kernel#eval with the given args but catches posible errors
|
11
|
+
def resilient_eval( *args )
|
12
|
+
begin
|
13
|
+
begin
|
14
|
+
eval( *args )
|
15
|
+
rescue SyntaxError => e
|
16
|
+
e
|
17
|
+
end
|
18
|
+
rescue => e
|
19
|
+
e
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def p( obj ) #:nodoc:
|
24
|
+
puts obj.to_live_output
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class Object
|
30
|
+
|
31
|
+
# Outputs an ANSI colored string with the object representation
|
32
|
+
def to_live_output
|
33
|
+
case self
|
34
|
+
when Exception
|
35
|
+
"\e[41m\e[33m#{self.inspect}\e[0m"
|
36
|
+
when Numeric, Symbol, TrueClass, FalseClass, NilClass
|
37
|
+
"\e[35m#{self.inspect}\e[0m"
|
38
|
+
when Notice
|
39
|
+
"\e[42m\e[30m#{self}\e[0m"
|
40
|
+
when Warning
|
41
|
+
"\e[43m\e[30m#{self}\e[0m"
|
42
|
+
when Special
|
43
|
+
"\e[44m\e[37m#{self}\e[0m"
|
44
|
+
when String
|
45
|
+
"\e[32m#{self.inspect}\e[0m"
|
46
|
+
when Array
|
47
|
+
"[#{ self.collect{ |i| i.to_live_output}.join(', ') }]"
|
48
|
+
when Hash
|
49
|
+
"{#{ self.collect{ |i| i.collect{|e| e.to_live_output}.join(' => ') } }}"
|
50
|
+
else
|
51
|
+
"\e[36m#{self}\e[0m"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Notice < String; end
|
57
|
+
class Warning < String; end
|
58
|
+
class Special < String; end
|
59
|
+
|
60
|
+
module Live
|
61
|
+
class Pipe < Tempfile
|
62
|
+
def make_tmpname( *args )
|
63
|
+
"ruby_live.pipe"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Session
|
68
|
+
include HighLine::SystemExtensions
|
69
|
+
|
70
|
+
# Starts a live session using a named pipe to receive code from a remote source and evaluates it within a context, a bit like an IRB session but evaluates code sent from a text editor
|
71
|
+
def initialize
|
72
|
+
return p( Exception.new("Another session sems to be running") ) if File.exist?( "#{Dir.tmpdir}/ruby_live.pipe" )
|
73
|
+
p( Notice.new("Live Session") )
|
74
|
+
get_binding
|
75
|
+
init_pipe
|
76
|
+
expect_input
|
77
|
+
serve
|
78
|
+
end
|
79
|
+
|
80
|
+
def init_pipe
|
81
|
+
@pipe_path = Pipe.new('').path
|
82
|
+
`rm #{@pipe_path}; mkfifo #{@pipe_path}`
|
83
|
+
end
|
84
|
+
|
85
|
+
# Starts a loop that checks the named pipe and evaluate its contents, will be called on initialize
|
86
|
+
def serve
|
87
|
+
File.open( @pipe_path, File::RDONLY | File::NONBLOCK) do |f|
|
88
|
+
loop { p evaluate( f.gets.to_s.gsub("∂", "\n") ) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Starts a new Thread that will loop capturing keystrokes and evaluating the bound block within the @context Binding, will be called on initialize
|
93
|
+
def expect_input
|
94
|
+
Thread.new do
|
95
|
+
loop do
|
96
|
+
char = get_character
|
97
|
+
@bindings ||= []
|
98
|
+
bind = @bindings[ char ]
|
99
|
+
p evaluate( bind ) if bind
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Expects a one char Symbol or String which will bind to a passed block so it can be called later with a keystroke
|
105
|
+
def bind( key, &block )
|
106
|
+
@bindings = [] unless @bindings.instance_of?(Array)
|
107
|
+
block ||= Proc.new{}
|
108
|
+
@bindings[ key.to_s[0] ] = Ruby2Ruby.new.process( [:block, block.to_sexp.last] )
|
109
|
+
Notice.new( "Key '#{key}' is bound to an action")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Evaluates a ruby expression within the @context Binding
|
113
|
+
def evaluate( string = nil )
|
114
|
+
return resilient_eval( string, @context ) if string
|
115
|
+
end
|
116
|
+
|
117
|
+
def clear
|
118
|
+
print "\e[2J\e[f"
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_binding #:nodoc:
|
122
|
+
@context = binding
|
123
|
+
end
|
124
|
+
|
125
|
+
def run_updates( code )
|
126
|
+
source = ParseTree.new.parse_tree_for_string( code ).first
|
127
|
+
final = []
|
128
|
+
while iter = source.assoc(:iter)
|
129
|
+
source -= [iter]
|
130
|
+
final << [:block, iter.last] if iter[1].include?(:update)
|
131
|
+
end
|
132
|
+
evaluate( final.collect{ |exp| Ruby2Ruby.new.process(exp) }.join("\n") )
|
133
|
+
Notice.new('Update blocks evaluated')
|
134
|
+
end
|
135
|
+
|
136
|
+
def update # Allmost a stub
|
137
|
+
yield
|
138
|
+
end
|
139
|
+
|
140
|
+
alias :reaload! :get_binding
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
data/lib/scruby.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 Macario Ortega
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#++
|
17
|
+
require 'rubygems'
|
18
|
+
require 'ruby2ruby'
|
19
|
+
require "named_arguments"
|
20
|
+
require 'osc'
|
21
|
+
require 'yaml'
|
22
|
+
|
23
|
+
SCRUBY_DIR = File.join( File.expand_path(File.dirname(__FILE__) ), 'scruby' )
|
24
|
+
|
25
|
+
|
26
|
+
require "#{SCRUBY_DIR}/typed_array"
|
27
|
+
|
28
|
+
require "#{SCRUBY_DIR}/audio/ugens/ugen_operations"
|
29
|
+
require "#{SCRUBY_DIR}/audio/ugens/ugen"
|
30
|
+
require "#{SCRUBY_DIR}/audio/ugens/multi_out_ugens"
|
31
|
+
require "#{SCRUBY_DIR}/audio/ugens/in_out"
|
32
|
+
|
33
|
+
require "#{SCRUBY_DIR}/audio/ugens/operation_ugens"
|
34
|
+
require "#{SCRUBY_DIR}/audio/ugens/ugen"
|
35
|
+
|
36
|
+
require "#{SCRUBY_DIR}/audio/ugens/ugens"
|
37
|
+
require "#{SCRUBY_DIR}/audio/control_name"
|
38
|
+
require "#{SCRUBY_DIR}/audio/synthdef"
|
39
|
+
require "#{SCRUBY_DIR}/extensions"
|
40
|
+
|
41
|
+
require "#{SCRUBY_DIR}/audio/server"
|
42
|
+
|
43
|
+
require "#{SCRUBY_DIR}/audio/env"
|
44
|
+
require "#{SCRUBY_DIR}/audio/ugens/env_gen"
|
45
|
+
|
46
|
+
require "#{SCRUBY_DIR}/audio/node"
|
47
|
+
require "#{SCRUBY_DIR}/audio/synth"
|
48
|
+
|
49
|
+
|
50
|
+
include Scruby
|
51
|
+
include Audio
|
52
|
+
include Ugens
|
53
|
+
include OperationUgens
|
54
|
+
|
55
|
+
|
56
|
+
class Notice < String; end
|
57
|
+
class Warning < String; end
|
58
|
+
class Special < String; end
|
59
|
+
|
60
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Scruby
|
2
|
+
module Audio
|
3
|
+
class ControlName
|
4
|
+
attr_accessor :name, :value, :rate, :index
|
5
|
+
RATES = { 'n_' => :noncontrol, 'i_' => :scalar, 'k_' => :control, 't_' => :trigger }
|
6
|
+
|
7
|
+
def initialize( name, value, rate, index )
|
8
|
+
@name, @value, @rate, @index = name.to_s, value.to_f, set_rate( name, rate ), index
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_rate( name, rate )
|
12
|
+
RATES.has_value?( rate ) ? rate : rate_from_name( name )
|
13
|
+
end
|
14
|
+
|
15
|
+
def rate_from_name( name )
|
16
|
+
RATES[ name.to_s[0..1] ] || :control
|
17
|
+
end
|
18
|
+
|
19
|
+
def non_control?
|
20
|
+
@rate == :noncontrol
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_ugen_input?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Scruby
|
2
|
+
class Env
|
3
|
+
attr_accessor :levels, :times, :curves, :release_node, :array
|
4
|
+
SHAPE_NAMES = {
|
5
|
+
:step => 0,
|
6
|
+
:lin => 1,
|
7
|
+
:linear => 1,
|
8
|
+
:exp => 2,
|
9
|
+
:exponential => 2,
|
10
|
+
:sin => 3,
|
11
|
+
:sine => 3,
|
12
|
+
:wel => 4,
|
13
|
+
:welch => 4,
|
14
|
+
:sqr => 6,
|
15
|
+
:squared => 6,
|
16
|
+
:cub => 7,
|
17
|
+
:cubed => 7
|
18
|
+
}
|
19
|
+
|
20
|
+
def initialize( levels, times, curves = :lin, release_node = nil, loop_node = nil )
|
21
|
+
@levels, @times, @curves, @release_node, @loop_node = levels, times, curves.to_array, release_node, loop_node
|
22
|
+
raise ArgumentError, "levels and times should be array" unless levels.instance_of?(Array) and times.instance_of?(Array)
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
# fixed duration envelopes
|
27
|
+
def triangle(dur = 1.0, level = 1.0)
|
28
|
+
dur = (dur * 0.5)
|
29
|
+
new( [0, level, 0], [dur, dur] )
|
30
|
+
end
|
31
|
+
|
32
|
+
def sine(dur = 1.0, level = 1.0)
|
33
|
+
dur = (dur * 0.5)
|
34
|
+
new( [0, level, 0], [dur, dur], :sine)
|
35
|
+
end
|
36
|
+
|
37
|
+
def perc( attackTime=0.01, releaseTime=1.0, level=1.0, curve = -4.0 )
|
38
|
+
new( [0, level, 0], [attackTime, releaseTime], curve )
|
39
|
+
end
|
40
|
+
|
41
|
+
def linen( attackTime=0.01, sustainTime=1.0, releaseTime=1.0, level=1.0, curve = :lin )
|
42
|
+
new [0, level, level, 0], [attackTime, sustainTime, releaseTime], curve
|
43
|
+
end
|
44
|
+
|
45
|
+
def cutoff( releaseTime = 0.1, level = 1.0, curve = :lin )
|
46
|
+
new( [level, 0], [releaseTime], curve, 0 )
|
47
|
+
end
|
48
|
+
|
49
|
+
def dadsr( delayTime=0.1, attackTime=0.01, decayTime=0.3, sustainLevel=0.5, releaseTime=1.0, peakLevel=1.0, curve = -4.0, bias = 0.0 )
|
50
|
+
new( [0, 0, peakLevel, peakLevel * sustainLevel, 0].collect{ |e| e + bias }, [delayTime, attackTime, decayTime, releaseTime], curve, 3 )
|
51
|
+
end
|
52
|
+
|
53
|
+
def adsr( attackTime=0.01, decayTime=0.3, sustainLevel=0.5, releaseTime=1.0, peakLevel=1.0, curve = -4.0, bias = 0.0 )
|
54
|
+
new( [0, peakLevel, peakLevel * sustainLevel, 0].collect{ |e| e + bias }, [attackTime, decayTime, releaseTime], curve, 2 )
|
55
|
+
end
|
56
|
+
|
57
|
+
def asr( attackTime=0.01, sustainLevel=1.0, releaseTime=1.0, curve = -4.0 )
|
58
|
+
new( [0, sustainLevel, 0], [attackTime, releaseTime], curve, 1 )
|
59
|
+
end
|
60
|
+
|
61
|
+
named_args_for :triangle, :sine, :perc, :linen, :cutoff, :dadsr, :adsr, :asr
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_array
|
65
|
+
*contents = levels[0], times.size, release_node, loop_node
|
66
|
+
contents + levels[1..-1].wrap_and_zip( times, shape_numbers, curve_values ).flatten
|
67
|
+
end
|
68
|
+
|
69
|
+
def shape_numbers
|
70
|
+
curves.collect do |curve|
|
71
|
+
curve.valid_ugen_input? ? 5 : SHAPE_NAMES[curve]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def curve_values
|
76
|
+
curves.collect do |curve|
|
77
|
+
curve.valid_ugen_input? ? curve : 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def release_node
|
82
|
+
@release_node ||= -99
|
83
|
+
end
|
84
|
+
|
85
|
+
def loop_node
|
86
|
+
@loop_node ||= -99
|
87
|
+
end
|
88
|
+
|
89
|
+
def valid_ugen_input? #returns true
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
93
|
+
def collect_constants #:nodoc:
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Scruby
|
2
|
+
class Node
|
3
|
+
@@base_id = 2000
|
4
|
+
attr_reader :name, :servers
|
5
|
+
|
6
|
+
def initialize( name, *servers )
|
7
|
+
@name = name.to_s
|
8
|
+
servers = *servers
|
9
|
+
@servers = servers ? TypedArray.new( Server, [*servers] ) : Server.all
|
10
|
+
end
|
11
|
+
|
12
|
+
def id
|
13
|
+
@id ||= ( @@base_id = @@base_id + 1 )
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.reset!
|
17
|
+
@@base_id = 2000
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|