maca-Scruby 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|