scruby 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +53 -0
  5. data/README.rdoc +65 -0
  6. data/Rakefile +10 -0
  7. data/TODO.markdown +3 -0
  8. data/examples/example.rb +73 -0
  9. data/lib/scruby/buffer.rb +153 -0
  10. data/lib/scruby/bus.rb +67 -0
  11. data/lib/scruby/control_name.rb +29 -0
  12. data/lib/scruby/core_ext/array.rb +44 -0
  13. data/lib/scruby/core_ext/delegator_array.rb +44 -0
  14. data/lib/scruby/core_ext/fixnum.rb +8 -0
  15. data/lib/scruby/core_ext/numeric.rb +25 -0
  16. data/lib/scruby/core_ext/object.rb +23 -0
  17. data/lib/scruby/core_ext/proc.rb +11 -0
  18. data/lib/scruby/core_ext/string.rb +5 -0
  19. data/lib/scruby/core_ext/symbol.rb +5 -0
  20. data/lib/scruby/core_ext/typed_array.rb +54 -0
  21. data/lib/scruby/env.rb +93 -0
  22. data/lib/scruby/group.rb +24 -0
  23. data/lib/scruby/node.rb +102 -0
  24. data/lib/scruby/server.rb +182 -0
  25. data/lib/scruby/synth.rb +50 -0
  26. data/lib/scruby/synthdef.rb +109 -0
  27. data/lib/scruby/ticker.rb +92 -0
  28. data/lib/scruby/ugens/buffer_read_write.rb +98 -0
  29. data/lib/scruby/ugens/demand.rb +9 -0
  30. data/lib/scruby/ugens/disk_in_out.rb +33 -0
  31. data/lib/scruby/ugens/env_gen.rb +38 -0
  32. data/lib/scruby/ugens/in_out.rb +46 -0
  33. data/lib/scruby/ugens/multi_out.rb +53 -0
  34. data/lib/scruby/ugens/operation_indices.yaml +92 -0
  35. data/lib/scruby/ugens/operation_ugens.rb +63 -0
  36. data/lib/scruby/ugens/panner.rb +137 -0
  37. data/lib/scruby/ugens/ugen.rb +173 -0
  38. data/lib/scruby/ugens/ugen_defs.yaml +3123 -0
  39. data/lib/scruby/ugens/ugen_operations.rb +57 -0
  40. data/lib/scruby/ugens/ugens.rb +95 -0
  41. data/lib/scruby/version.rb +3 -0
  42. data/lib/scruby.rb +65 -0
  43. data/scruby.gemspec +27 -0
  44. data/spec/buffer_read_write_spec.rb +333 -0
  45. data/spec/buffer_spec.rb +199 -0
  46. data/spec/bus_spec.rb +184 -0
  47. data/spec/core_ext/core_ext_spec.rb +120 -0
  48. data/spec/core_ext/delegator_array_spec.rb +144 -0
  49. data/spec/core_ext/typed_array_spec.rb +95 -0
  50. data/spec/demand_spec.rb +81 -0
  51. data/spec/disk_in_out_spec.rb +138 -0
  52. data/spec/env_gen_spec.rb +23 -0
  53. data/spec/env_spec.rb +73 -0
  54. data/spec/group_spec.rb +71 -0
  55. data/spec/helper.rb +20 -0
  56. data/spec/in_out_spec.rb +127 -0
  57. data/spec/integration_spec.rb +88 -0
  58. data/spec/multiout_ugen_spec.rb +86 -0
  59. data/spec/node_spec.rb +112 -0
  60. data/spec/operation_ugens_spec.rb +196 -0
  61. data/spec/panner_spec.rb +271 -0
  62. data/spec/server.rb +12 -0
  63. data/spec/server_spec.rb +198 -0
  64. data/spec/synth_spec.rb +103 -0
  65. data/spec/synthdef_spec.rb +267 -0
  66. data/spec/ugen_operations_spec.rb +100 -0
  67. data/spec/ugen_spec.rb +356 -0
  68. data/spec/ugens_spec.rb +65 -0
  69. metadata +207 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *.swp
5
+ *.swo
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in scruby.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scruby (0.2.7)
5
+ arguments (~> 0.6)
6
+ live (~> 0.1)
7
+ ruby-osc (~> 0.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ ParseTree (3.0.7)
13
+ RubyInline (>= 3.7.0)
14
+ sexp_processor (>= 3.0.0)
15
+ RubyInline (3.9.0)
16
+ ZenTest (~> 4.3)
17
+ ZenTest (4.5.0)
18
+ arguments (0.6)
19
+ ParseTree (>= 3.0.3)
20
+ ruby2ruby (= 1.1.9)
21
+ ruby_parser (>= 2.0.2)
22
+ diff-lcs (1.1.2)
23
+ eventmachine (0.12.10)
24
+ highline (1.6.1)
25
+ hoe (2.9.1)
26
+ rake (>= 0.8.7)
27
+ live (0.1.2)
28
+ highline
29
+ rake (0.8.7)
30
+ rspec (2.5.0)
31
+ rspec-core (~> 2.5.0)
32
+ rspec-expectations (~> 2.5.0)
33
+ rspec-mocks (~> 2.5.0)
34
+ rspec-core (2.5.1)
35
+ rspec-expectations (2.5.0)
36
+ diff-lcs (~> 1.1.2)
37
+ rspec-mocks (2.5.0)
38
+ ruby-osc (0.3.2)
39
+ eventmachine (>= 0.12.8)
40
+ ruby2ruby (1.1.9)
41
+ ParseTree
42
+ hoe (>= 1.5.3)
43
+ ruby_parser (2.0.6)
44
+ sexp_processor (~> 3.0)
45
+ sexp_processor (3.0.5)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ bundler
52
+ rspec
53
+ scruby!
data/README.rdoc ADDED
@@ -0,0 +1,65 @@
1
+ == Scruby
2
+
3
+ Is a bare-bones SuperCollider livecoding library for Ruby, it provides comunication with a remote or local scsynth server and SynthDef creation with a
4
+ in a similar way to Sclang.
5
+
6
+ SynthDef creation and sending is robust but some features are not implemented such as SynthDef variations and others I may not be aware of.
7
+
8
+ livecode.rb executable is located in the bin directory and a TextMate bundle included in extras permits livecoding from TextMate, comunication is
9
+ thrugh *nix pipes. Similar functionality shouldn't be too dificult to implement from Emacs or Vim.
10
+
11
+ == INSTALL
12
+
13
+ $ [sudo] gem install scruby
14
+
15
+
16
+ == USAGE
17
+
18
+ require 'scruby'
19
+
20
+ s = Server.new
21
+ s.boot
22
+
23
+ SynthDef.new :fm do |freq, amp, dur|
24
+ mod_env = EnvGen.kr Env.new( d(600, 200, 100), d(0.7,0.3) ), 1, :timeScale => dur
25
+ mod = SinOsc.ar freq * 1.4, :mul => mod_env
26
+ sig = SinOsc.ar freq + mod
27
+ env = EnvGen.kr Env.new( d(0, 1, 0.6, 0.2, 0.1, 0), d(0.001, 0.005, 0.3, 0.5, 0.7) ), 1, :timeScale => dur, :doneAction => 2
28
+ sig = sig * amp * env
29
+ Out.ar 0, [sig, sig]
30
+ end.send
31
+
32
+ Synth.new :fm, :freq => 220, :amp => 0.4, :dur => 1
33
+
34
+
35
+ To start a live coding session:
36
+
37
+ $ live
38
+
39
+ See http://github.com/maca/live
40
+
41
+
42
+ == TODO
43
+
44
+ Receive OSC messages from SuperCollider
45
+
46
+ == LICENSE:
47
+
48
+ Copyright (c) 2008 Macario Ortega
49
+
50
+ This program is free software: you can redistribute it and/or modify
51
+ it under the terms of the GNU General Public License as published by
52
+ the Free Software Foundation, either version 3 of the License, or
53
+ (at your option) any later version.
54
+
55
+ This program is distributed in the hope that it will be useful,
56
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
57
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58
+ GNU General Public License for more details.
59
+
60
+ You should have received a copy of the GNU General Public License
61
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
62
+
63
+
64
+
65
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require "rspec/core/rake_task"
4
+
5
+ desc "Run specs"
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
9
+
10
+ Bundler::GemHelper.install_tasks
data/TODO.markdown ADDED
@@ -0,0 +1,3 @@
1
+ **Array workarrounds**
2
+
3
+ * Buffer as Ugen input
@@ -0,0 +1,73 @@
1
+ scruby = "#{File.expand_path( File.join( File.dirname( __FILE__), '..', 'scruby' ) )}"
2
+ require scruby
3
+ s = Server.new('localhost', 57140)
4
+ s.boot
5
+ require File.expand_path( File.join( File.dirname(__FILE__),'..','..', '..', 'Sequentiable', 'lib', 'metro' ) )
6
+ require File.expand_path( File.join( File.dirname(__FILE__),'..','..', '..', 'HumanGenome', 'lib', 'human_genome' ) )
7
+
8
+ sdef = SynthDef.new :melo, :values => [456, 0.34, 0.45] do |freq, amp, a, b, c|
9
+ gate = EnvGen.kr( Env.perc(0, 0.2) )
10
+ sig = SinOsc.ar( [freq, freq * 1.01], :mul => SinOsc.kr(40) * amp * 0.7, :add => SinOsc.kr(0.5, :mul => 2.5) ) * EnvGen.kr( Env.asr(2, 1, 3), gate, :doneAction => 2 )
11
+ sig = SinOsc.ar( [freq, freq * 1.01], :mul => SinOsc.kr(8) * amp * 0.3, :add => SinOsc.kr(0.5, :mul => 2.5) ) * EnvGen.kr( Env.asr(2, 1, 2), gate ) + sig
12
+ sig = SinOsc.ar( [freq * 0.25, freq * 0.251], :mul => SinOsc.kr(30) * amp * 0.3 ) * EnvGen.kr( Env.asr(2, 1, 3), gate ) + sig
13
+ sig = SinOsc.ar( freq * 2, :mul => SinOsc.kr(500, :mul => 0.1) * amp * 0.1 ) * EnvGen.kr( Env.asr(0, 1, 2), gate ) + sig
14
+ sig = SinOsc.ar( freq * 0.25, :mul => amp * 0.2 ) * EnvGen.kr( Env.asr(0, 1, 0.4), gate ) + sig
15
+ res = Resonz.ar( sig, EnvGen.kr( Env.asr(0.5, 3,c*2) )* a * 10000 )
16
+ Out.ar( 0, [res[0] * 6 + sig[1] * 0.8]*2 )
17
+ end
18
+ sdef.send
19
+ sleep 0.05
20
+ test = Synth.new :melo, :freq => 220, :amp => 0.5
21
+
22
+ # [1] * 2 = [1,1]
23
+
24
+ s.stop
25
+
26
+
27
+ sdef = SynthDef.new :perc, :values => [456, 0.34, 0.45] do |freq, amp, a, b|
28
+ dur = a
29
+ amp = amp * 0.25
30
+ freq = freq * 0.05
31
+ sig = SinOsc.ar( Line.kr( freq * 1.5, freq * 1.1, dur ), Math::PI/2, amp * 0.2 * SinOsc.kr(10) )
32
+ # sig = Resonz.ar( sig, EnvGen.kr( Env.asr(0.5, 3, 2) ) * 120, 0.5 )
33
+ # sig = LPF.ar( sig, 120 )
34
+ sig = HPF.ar( WhiteNoise.ar( amp * 0.1 ), freq * 10 ) * b * 0.8 + sig
35
+ # sig = Pan2.ar( sig, 0)
36
+ env = EnvGen.kr Env.perc( 0, dur ), :doneAction => 2
37
+ Out.ar 0, [sig*env]*2
38
+ end
39
+ sdef.send
40
+ sleep 0.05
41
+ test = Synth.new :perc, :freq => 1000, :amp => 0.5, :dur => rand
42
+
43
+ sdef = SynthDef.new :perc, :values => [456, 0.34, 0.45] do |freq, amp, a, b|
44
+ dur = a
45
+ amp = amp
46
+ freq = freq * 0.1
47
+ sig = SinOsc.ar( Line.kr( freq * 1.5, freq * 1.1, dur ), Math::PI/2, amp * 0.2 * SinOsc.kr(10) )
48
+ sig = HPF.ar( WhiteNoise.ar( amp * 0.1 ), freq * 10 ) * 0.8 + sig
49
+ env = EnvGen.kr Env.perc( 0, dur ), :doneAction => 2
50
+ Out.ar 0, [sig*env]*2
51
+ end
52
+ sdef.send
53
+ sleep 0.05
54
+ test = Synth.new :perc, :freq => 1000, :amp => 0.5, :dur => rand
55
+
56
+ sdef = SynthDef.new :perc, :values => [456, 0.34, 0.45] do |freq, amp, a, b|
57
+ gate = EnvGen.kr Env.perc(0,0.1)
58
+ env = EnvGen.kr Env.asr( 0.1, 4, 1 ), gate, :doneAction => 2
59
+ sig = DelayC.ar( SinOsc.ar(freq), 4, SinOsc.ar( SinOsc.ar( SinOsc.ar( 2 ) ) ) )
60
+ Out.ar( 0, [sig * env]*2 )
61
+ end
62
+ sdef.send
63
+ sleep 0.05
64
+ test = Synth.new :perc, :freq => 1000, :amp => 0.5, :dur => rand
65
+ # sleep 0.8
66
+
67
+ s.stop
68
+
69
+ sleep 0.05
70
+ test = Synth.new :test, :freq => 20, :amp => 1
71
+
72
+
73
+
@@ -0,0 +1,153 @@
1
+ module Scruby
2
+ def expand_path path
3
+ path = "~/Scruby/#{ path }" unless path.match %r{^(?:/|~)}
4
+ File.expand_path path
5
+ end
6
+
7
+ class Buffer
8
+ # readNoUpdate
9
+ # loadCollection
10
+ # sendCollection
11
+ # streamCollection
12
+ # loadToFloatArray
13
+ # getToFloatArray
14
+ # set
15
+ # setn
16
+ # get
17
+ # getn
18
+ # fill
19
+ # normalize
20
+ # gen
21
+ # sine1
22
+ # ...
23
+ # copy
24
+ # copyData
25
+ # query
26
+ # updateInfo
27
+ # queryDone
28
+ # printOn
29
+ # play
30
+ # duration
31
+ # asBufWithValues
32
+
33
+ attr_reader :server
34
+ attr_accessor :path, :frames, :channels, :rate
35
+
36
+ def read path, file_start = 0, frames = -1, buff_start = 0, leave_open = false, &message
37
+ # @on_info = message
38
+ message ||= ["/b_query", buffnum]
39
+ @server.send "/b_read", buffnum, expand_path(path), file_start, frames, buff_start, leave_open, message.value(self)
40
+ self
41
+ end
42
+
43
+ def read_channel path, file_start = 0, frames = -1, buff_start = 0, leave_open = false, channels = [], &message
44
+ message ||= 0
45
+ @server.send *(["/b_ReadChannel", buffnum, expand_path(path), start, frames, buff_start, leave_open] + channels << message.value(self))
46
+ self
47
+ end
48
+
49
+ def close &message
50
+ message ||= 0
51
+ @server.send '/b_close', buffnum, message.value(self)
52
+ self
53
+ end
54
+
55
+ def zero &message
56
+ message ||= 0
57
+ @server.send '/b_zero', buffnum, message.value(self)
58
+ self
59
+ end
60
+
61
+ def cue_sound_file path, start = 0, &message
62
+ message ||= 0
63
+ @server.send "/b_read", buffnum, expand_path(path), start, @frames, 0, 1, message.value(self)
64
+ self
65
+ end
66
+
67
+ def write path = nil, format = 'aiff', sample_format = 'int24', frames = -1, start = 0, leave_open = false, &message
68
+ message ||= 0
69
+ path ||= "#{ DateTime.now }.#{ format }"
70
+ @server.send "/b_write", buffnum, expand_path(path), format, sample_format, frames, start, leave_open, message.value(self)
71
+ self
72
+ end
73
+
74
+ def initialize server, frames = -1, channels = 1
75
+ @server, @frames, @channels = server, frames, channels
76
+ end
77
+
78
+ def allocate &message
79
+ message ||= 0
80
+ @server.allocate :buffers, self
81
+ @server.send '/b_alloc', buffnum, frames, channels, message.value(self)
82
+ self
83
+ end
84
+
85
+ def buffnum
86
+ @server.buffers.index self
87
+ end
88
+ alias :as_ugen_input :buffnum
89
+ alias :index :buffnum
90
+ # alias :as_control_input :buffnum
91
+
92
+ def free &message
93
+ message ||= 0
94
+ @server.send "/b_free", buffnum, message.value(self)
95
+ @server.buffers.delete self
96
+ end
97
+
98
+ # :nodoc:
99
+ def allocate_and_read path, start, frames, &message
100
+ @server.allocate :buffers, self
101
+ message ||= ["/b_query", buffnum]
102
+ @server.send "/b_allocRead", buffnum, @path = expand_path(path), start, frames, message.value(self)
103
+ self
104
+ end
105
+
106
+ def allocate_read_channel path, start, frames, channels, &message
107
+ @server.allocate :buffers, self
108
+ message ||= ["/b_query", buffnum]
109
+ @server.send *(["/b_allocReadChannel", buffnum, expand_path(path), start, frames] + channels << message.value(self))
110
+ self
111
+ end
112
+
113
+ class << self
114
+ def allocate server, frames = -1, channels = 1, &message
115
+ new(server, frames, channels).allocate &message
116
+ end
117
+
118
+ def cue_sound_file server, path, start, channels = 2, buff_size = 32768, &message
119
+ allocate server, buff_size, channels do |buffer|
120
+ message ||= 0
121
+ ['/b_read', buffer.buffnum, expand_path(path), start, buff_size, 0, true, message.value(buffer)]
122
+ end
123
+ end
124
+
125
+ # Allocate a buffer and immediately read a soundfile into it.
126
+ def read server, path, start = 0, frames = -1, &message
127
+ buffer = new server, &message
128
+ buffer.allocate_and_read expand_path(path), start, frames
129
+ end
130
+
131
+ def read_channel server, path, start = 0, frames = -1, channels = [], &message
132
+ new(server, frames, channels).allocate_read_channel expand_path(path), start, frames, channels, &message
133
+ end
134
+
135
+ def alloc_consecutive buffers, server, frames = -1, channels = 1, &message
136
+ buffers = Array.new(buffers){ new server, frames, channels }
137
+ server.allocate :buffers, buffers
138
+ message ||= 0
139
+ buffers.each do |buff|
140
+ server.send '/b_alloc', buff.buffnum, frames, channels, message.value(buff)
141
+ end
142
+ end
143
+
144
+ named_arguments_for :allocate, :read, :cue_sound_file, :alloc_consecutive, :read_channel
145
+
146
+ # readNoUpdate
147
+ # loadCollection
148
+ # sendCollection
149
+ # loadDialog
150
+ end
151
+ end
152
+ end
153
+
data/lib/scruby/bus.rb ADDED
@@ -0,0 +1,67 @@
1
+ module Scruby
2
+
3
+ class Bus
4
+ attr_reader :server, :rate, :channels, :main_bus
5
+
6
+ def initialize server, rate, channels = 1, main_bus = self, hardware_out = false
7
+ @server, @rate, @channels, @main_bus, @hardware_out = server, rate, channels, main_bus, hardware_out
8
+ end
9
+
10
+ def index
11
+ @index ||= @server.__send__("#{ @rate }_buses").index(self)
12
+ end
13
+
14
+ def free
15
+ @index = nil
16
+ @server.__send__("#{ @rate }_buses").delete(self)
17
+ end
18
+
19
+ def to_map
20
+ raise SCError, 'Audio buses cannot be mapped' if rate == :audio
21
+ "c#{ index }"
22
+ end
23
+
24
+ def audio_out?
25
+ index < @server.instance_variable_get(:@opts)[:audio_outputs]
26
+ end
27
+
28
+ # Messaging
29
+ def set *args
30
+ args.flatten!
31
+ message_args = []
32
+ (index...channels).to_a.zip(args) do |chan, val|
33
+ message_args.push(chan).push(val) if chan and val
34
+ end
35
+ if args.size > channels
36
+ warn "You tried to set #{ args.size } values for bus #{ index } that only has #{ channels } channels, extra values are ignored."
37
+ end
38
+ @server.send '/c_set', *message_args
39
+ end
40
+
41
+ def fill value, channels = @channels
42
+ if channels > @channels
43
+ warn "You tried to set #{ channels } values for bus #{ index } that only has #{ @channels } channels, extra values are ignored."
44
+ end
45
+ @server.send '/c_fill', index, channels.min(@channels), value
46
+ end
47
+
48
+ class << self
49
+ private :new
50
+
51
+ def control server, channels = 1
52
+ buses = [new(server, :control, channels)]
53
+ buses.push new(server, :control, channels, buses.first) while buses.size < channels
54
+ server.allocate :control_buses, buses
55
+ buses.first
56
+ end
57
+
58
+ def audio server, channels = 1
59
+ buses = [new(server, :audio, channels)]
60
+ buses.push new(server, :audio, channels, buses.first) while buses.size < channels
61
+ server.allocate :audio_buses, buses
62
+ buses.first
63
+ end
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ module Scruby
2
+ class ControlName #:nodoc:
3
+ attr_accessor :name, :value, :rate, :index
4
+ RATES = { 'n_' => :noncontrol, 'i_' => :scalar, 'k_' => :control, 't_' => :trigger }
5
+
6
+ def initialize name, value, rate, index
7
+ @name, @value, @rate, @index = name.to_s, value.to_f, set_rate( name, rate ), index
8
+ end
9
+
10
+ def set_rate name, rate
11
+ RATES.has_value?( rate ) ? rate : rate_from_name( name )
12
+ end
13
+
14
+ def rate_from_name name
15
+ RATES[ name.to_s[0..1] ] || :control
16
+ end
17
+
18
+ def non_control?
19
+ @rate == :noncontrol
20
+ end
21
+
22
+ def == other
23
+ @name == other.name and
24
+ @value == other.value and
25
+ @rate == other.rate and
26
+ @index == other.index
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ class Array
2
+ #collect with index
3
+ def collect_with_index
4
+ self.zip( (0...self.size).map ).collect{ |element, index| yield element, index }
5
+ end
6
+
7
+ def wrap_to size
8
+ return self if size == self.size
9
+ self.dup.wrap_to! size
10
+ end
11
+
12
+ def wrap_to! size
13
+ return nil if size == self.size
14
+ original_size = self.size
15
+ size.times { |i| self[ i ] = self[ i % original_size ] }
16
+ self
17
+ end
18
+
19
+ def wrap_and_zip *args
20
+ max = args.map{ |a| instance_of?(Array) ? a.size : 0 }.max.max( self.size )
21
+ args = args.collect{ |a| a.to_array.wrap_to( max ) }
22
+ self.wrap_to( max ).zip( *args )
23
+ end
24
+
25
+ # Returns self
26
+ def to_array; self; end
27
+
28
+ def encode_floats #:nodoc:
29
+ [self.size].pack('n') + self.pack('g*') #TODO: Deprecate
30
+ end
31
+
32
+ def peel!
33
+ self.replace self.first if self.first.kind_of? Array if self.size == 1
34
+ end
35
+
36
+ def peel
37
+ self.dup.peel! || self
38
+ end
39
+
40
+ private
41
+ def collect_constants #:nodoc:
42
+ self.collect{ |e| e.send( :collect_constants ) }
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ class DelegatorArray < Array
2
+
3
+ def method_missing meth, *args, &block
4
+ return self.map! { |item| item.send meth, *args, &block }
5
+ end
6
+
7
+ def to_da; self; end
8
+ def to_a; Array.new self; end
9
+
10
+ [:*, :+, :-, :/].each do |meth|
11
+ define_method meth do |args|
12
+ binary_op meth, args
13
+ end
14
+ end
15
+
16
+ private
17
+ def binary_op op, inputs
18
+ return method_missing(op, inputs) unless inputs.kind_of? Array
19
+
20
+ results = self.class.new
21
+ self.zip(inputs).collect_with_index do |pair, index|
22
+ left, right = pair
23
+ next results.push(right) if index + 1 > self.size
24
+ next results.push(left) if index + 1 > inputs.size
25
+ results.push left.send(op, right)
26
+ end
27
+ results
28
+ end
29
+ end
30
+
31
+ class Array
32
+ def to_da
33
+ DelegatorArray.new self
34
+ end
35
+ end
36
+
37
+ module Kernel
38
+ def d *args
39
+ args.peel!
40
+ darray = DelegatorArray.new
41
+ darray.push *args
42
+ darray
43
+ end
44
+ end
@@ -0,0 +1,8 @@
1
+ # Musical math
2
+ class Fixnum
3
+ def freq
4
+ 440 * (2 ** ((self - 69) * 0.083333333333) )
5
+ end
6
+ #method next tone
7
+ # 1:1.05946
8
+ end
@@ -0,0 +1,25 @@
1
+ class Numeric
2
+ # Rate is :scalar
3
+ def rate; :scalar; end
4
+
5
+ # Compares itself with +other+ and returns biggest
6
+ def max other
7
+ self > other ? self : other
8
+ end
9
+
10
+ # Compares itself with +other+ and returns smallest
11
+ def min other
12
+ self < other ? self : other
13
+ end
14
+
15
+ private
16
+ #:nodoc:
17
+ def collect_constants
18
+ self
19
+ end
20
+
21
+ #:nodoc:
22
+ def input_specs synthdef
23
+ [-1, synthdef.constants.index(self)]
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ class Object
2
+ # Wraps self int an array, #to_a seems to be deprecated
3
+ def to_array
4
+ [*self]
5
+ end
6
+
7
+ def to_proc
8
+ Proc.new{ self }
9
+ end
10
+
11
+ def value *args
12
+ self
13
+ end
14
+ end
15
+
16
+
17
+ class TrueClass
18
+ def to_i; 1; end
19
+ end
20
+
21
+ class FalseClass
22
+ def to_i; 0; end
23
+ end
@@ -0,0 +1,11 @@
1
+ class Proc
2
+
3
+ def arguments
4
+ case self.arity
5
+ when -1..0 then []
6
+ when 1 then self.to_sexp.assoc( :dasgn_curr )[1].to_array
7
+ else self.to_sexp[2][1][1..-1].collect{ |arg| arg[1] }
8
+ end
9
+ end
10
+ alias :value :call
11
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def encode #:nodoc:
3
+ [self.size & 255].pack('C*') + self[0..255]
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Symbol
2
+ def to_proc
3
+ proc { |obj, *args| obj.send(self, *args) }
4
+ end
5
+ end