scruby 0.2.7

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.
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