Browse files

subclass of array that can do arithmetic with numeric and delegates u…

…ndefined methods to elements: d(1,2) + 1 == d(2,3) @SHDH Mexico
  • Loading branch information...
1 parent 448fa7e commit af0fe0c00698c902055f512d4131e7f01afc3b07 @maca maca committed Jul 25, 2009
Showing with 234 additions and 17 deletions.
  1. +16 −0 TODO.markdown
  2. +1 −1 lib/scruby/audio/server.rb
  3. +34 −0 lib/scruby/core_ext/delegator_array.rb
  4. +79 −0 spec/channel_array_spec.rb
  5. +4 −3 spec/core_ext_spec.rb
  6. +100 −13 test.live.rb
View
16 TODO.markdown
@@ -0,0 +1,16 @@
+
+
+**Array workarrounds**
+
+* If Synth is passed an array makes an array of synths that behave like one, freeing it frees all. DelegatorArray
+
+* Somehow let all elements of an array be multiplied by a number, maybe if the Numeric multiplies the Array, eg:
+
+ 2 * [1,2] == [2,4] and 2 * [1,2] == c[2,4] and ChannelArray.new(2,4) # => true (DONE)
+
+* Maybe the result of a multichannel Ugen could be an instance of Array with binary operators overriden, eg:
+
+ mc = SinOsc.ar [400,402]
+ mc * 0.5 == c(SinOsc.ar(400) * 0.5, SinOsc.ar(402) * 0.5) # => true
+
+* "Literal" for ChannelArray c[] or c()
View
2 lib/scruby/audio/server.rb
@@ -155,7 +155,7 @@ def allocate kind, *elements
raise SCError, "No more indices available -- free some #{ kind } before allocating more."
end
- return collection.concat elements unless collection.index nil # just concat arrays if no nil item
+ return collection.concat(elements) unless collection.index nil # just concat arrays if no nil item
indices = []
collection.each_with_index do |item, index| # find n number of consecutive nil indices
View
34 lib/scruby/core_ext/delegator_array.rb
@@ -0,0 +1,34 @@
+class DelegatorArray < Array
+
+ def method_undefined meth, args
+ return self.class.new( self.map { |item| item.send meth, args } ) unless args.kind_of? Array
+
+ results = self.class.new
+ self.zip(args).collect_with_index do |pair, index|
+ left, right = pair
+
+ next results.push(right) if index + 1 > self.size
+ next results.push(left) if index + 1 > args.size
+
+ results.push left.send(meth, right)
+ end
+
+ results
+
+ end
+
+ [:*, :+, :-, :/].each do |meth|
+ define_method meth do |*args|
+ method_undefined meth, *args
+ end
+ end
+end
+
+module Kernel
+ def d *args
+ args.peel!
+ carray = DelegatorArray.new
+ carray.push *args
+ carray
+ end
+end
View
79 spec/channel_array_spec.rb
@@ -0,0 +1,79 @@
+require File.join( File.expand_path(File.dirname(__FILE__)), "helper")
+require "scruby/core_ext/array"
+require "scruby/core_ext/delegator_array"
+
+
+describe DelegatorArray do
+
+ it "should have 'literal' notation" do
+ d(1,2).should == [1,2]
+ d(1,2).should be_instance_of(DelegatorArray)
+ d([1,2]).should == d(1,2)
+ end
+
+ it "should allow nil" do
+ d(nil)
+ end
+
+ shared_examples_for 'aritmetic operand' do
+ before do
+ @numeric_op = eval %{ d(1,2) #{ @op } 3.0 }
+ @array_op = eval %{ d(1,2) #{ @op } d(1.0, 2.0) }
+ @asim_array_op1 = eval %{ d(1,2,3) #{ @op } d(1.0, 2.0) }
+ end
+
+ it "should do operation" do
+ @numeric_op.should == @numeric_op
+ @numeric_op.should be_a(DelegatorArray)
+ end
+
+ it "should do operation with array of the same size" do
+ @array_op.should == @array_result
+ @array_op.should be_a(DelegatorArray)
+ end
+
+ it "should do operation with array of diferent size (left bigger)" do
+ @asim_array_op1.should == @asim_result1
+ @asim_array_op1.should be_a(DelegatorArray)
+ end
+
+ it "should blow pass nil" do
+ lambda { d(nil,2,3) + 1 }.should raise_error(NoMethodError)
+ end
+ end
+
+ describe "should override sum" do
+ before do
+ @op = '+'
+ @array_result = d(1+1.0, 2+2.0)
+ @asim_result1 = d(1+1.0, 2+2.0, 3)
+ end
+ it_should_behave_like 'aritmetic operand'
+ end
+
+ describe "should override subs" do
+ before do
+ @op = '-'
+ @array_result = d(1-1.0, 2-2.0)
+ @asim_result1 = d(1-1.0, 2-2.0, 3)
+ end
+ end
+
+ describe "should override mult" do
+ before do
+ @op = '*'
+ @array_result = d(1*1.0, 2*2.0)
+ @asim_result1 = d(1*1.0, 2*2.0, 3)
+ end
+ it_should_behave_like 'aritmetic operand'
+ end
+
+ describe "should override div" do
+ before do
+ @op = '/'
+ @array_result = d(1/1.0, 2/2.0)
+ @asim_result1 = d(1/1.0, 2/2.0, 3)
+ end
+ it_should_behave_like 'aritmetic operand'
+ end
+end
View
7 spec/core_ext_spec.rb
@@ -3,10 +3,10 @@
describe Numeric do
before :all do
- @bin_op = mock 'binop'
+ @bin_op = mock 'binop'
::BinaryOpUGen = mock 'BinaryOpUGen', :new => @bin_on
- @ugen = mock 'ugen'
- ::Ugen = mock 'Ugen', :new => @ugen
+ @ugen = mock 'ugen'
+ ::Ugen = mock 'Ugen', :new => @ugen
end
it "shoud have an scalar rate" do
@@ -116,3 +116,4 @@
end
+
View
113 test.live.rb
@@ -1,19 +1,11 @@
load File.expand_path( File.dirname( __FILE__ ) + '/../scruby.rb' )
-s = Server.new('localhost', 57140)
+s = Server.new
s.boot
-# Lamonte Young - Just in tone afination
-# Nan Carrow
-# Stockhausen
-44100
-
+10.times { |i| print "hola #{i}" }
-s.send "/dumpOSC", 0
-
-clear
-
-warn 'hi'
+1+1
# Síntesis aditiva básica
SynthDef.new :add do
@@ -46,7 +38,6 @@
s.stop
-warn 'hi'
# Construcción de una onda cuadrada
SynthDef.new :simple do |freq, mul, dur|
@@ -126,4 +117,100 @@
s.stop
-In
+
+
+# Síntesis por FM
+SynthDef.new :campana do |freq, amp, dur|
+ gate = EnvGen.kr Env.perc(0, 0.2)
+ mod_env = EnvGen.kr Env.new([600, 200, 100], [0.7,0.3].map{|v|v*dur}), gate
+ mod = SinOsc.ar freq * 1.4, :mul => mod_env
+ sig = SinOsc.ar freq + mod
+ env = EnvGen.kr Env.new( [0, 1, 0.6, 0.2, 0.1, 0 ], [0.001, 0.005, 0.3, 0.5, 0.7].map{|v|v*dur} ), gate, :doneAction => 2
+ sig = sig * amp * env
+ Out.ar [sig, sig]
+end.send
+
+camp = Synth.new :campana, :freq => 250, :amp => 0.8, :dur => 5
+camp = Synth.new :campana, :freq => 20, :amp => 0.8, :dur => 6
+
+
+
+
+# Chido
+SynthDef.new :wood_drum do |freq, amp, dur|
+ gate = EnvGen.kr Env.perc(0, 0.2)
+ mod_env = EnvGen.kr Env.new([1600, 200, 50, 90, 10], [0.7,0.3,0.4,0.4].map{|v|v*dur}), gate
+ mod = SinOsc.ar freq * 0.6875, :mul => mod_env
+ sig = SinOsc.ar freq + mod
+ env = EnvGen.kr Env.new( [0, 1, 0.6, 0.2, 0.1, 0 ], [0.1, 0.5, 0.5, 0.7, 0.9].map{|v|v*dur} ), gate, :doneAction => 2
+ sig = sig * amp * env
+ Out.ar [sig, sig]
+end.send
+
+camp = Synth.new :wood_drum, :freq => 184, :amp => 0.8, :dur => 10
+camp = Synth.new :wood_drum, :freq => 180, :amp => 0.8, :dur => 10
+
+
+
+
+
+# Síntesis por FM
+SynthDef.new :"metales" do |freq, amp, dur|
+ mod_freq = freq * 5
+ gate = EnvGen.kr Env.perc(0, 0.2)
+ mod_env = EnvGen.kr Env.new([0, 1, 0], [0.1,0.3].map{|v|v*dur}), gate
+ mod = SinOsc.ar mod_freq, :mul => mod_env
+ sig = SinOsc.ar freq + mod
+ env = EnvGen.kr Env.new( [0, 1, 0.6, 0.2, 0.1, 0 ], [0.1, 0.5, 0.3, 0.5, 0.7].map{|v|v*dur} ), gate, :doneAction => 2
+ sig = sig * amp * env
+ Out.ar [sig, sig]
+end.send
+
+
+camp = Synth.new :"metales", :freq => 200, :amp => 0.8, :dur => 100
+
+s.stop
+
+
+
+camp.free
+
+[0.001, 0.005, 0.3, 0.5, 0.6].inject{ |sum, val| sum + val * 10 }
+
+
+
+# Convolución
+# Artículo Rhodes tutorial
+# Multiplicación de dos señales, el resultado es todo lo que coincide en las dos señales
+
+
+buffer = Buffer.read s, "sounds/Sound0.aiff", :frames => 10460
+
+
+
+
+SynthDef.new :convo do |dur, buffnum|
+ sig = WhiteNoise.ar
+ sig *= EnvGen.kr Env.perc(0, 0.5), :doneAction => 2
+ buff = PlayBuf.ar buffnum, :rate => 0.6, :loop => 1.0
+ sig = Convolution.ar buff, sig, 1024, 0.5
+ Out.ar 0, [sig, sig]
+end.send
+
+
+Synth.new :convo, :dur => 1, :buffnum => buffer.buffnum
+
+
+
+
+
+
+
+
+# Radios que funcionan para
+
+
+
+# Lamonte Young - Just in tone afination
+# Nan Carrow
+# Stockhausen

0 comments on commit af0fe0c

Please sign in to comment.