ruck 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/ruck_midi DELETED
@@ -1,151 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
-
4
- require "ruck"
5
-
6
- require "rubygems"
7
- require "midilib"
8
- require "midiator"
9
-
10
- # configuration
11
- if ARGV.length < 4
12
- puts "ruby midilib_runner.rb MIDI_FILENAME NUM_TRACKS LIVE SCRIPT_FILENAME [...]"
13
- exit 1
14
- end
15
-
16
- MIDI_FILENAME = ARGV[0]
17
- NUM_TRACKS = ARGV[1].to_i
18
- ALSO_LIVE = ["yes", "true", "1", "yeah"].include? ARGV[2].downcase
19
- FILENAMES = ARGV[3..-1]
20
-
21
- class MIDIShreduler < Ruck::Shreduler
22
- def run
23
- @start_time = Time.now
24
- super
25
- end
26
-
27
- def sim_to(new_now)
28
- d = new_now - @now
29
- TRACK_DELTAS.each_with_index do |delta, i|
30
- TRACK_DELTAS[i] = delta + d
31
- end
32
-
33
- # sync with wall clock
34
- if ALSO_LIVE
35
- actual_now = Time.now
36
- simulated_now = @start_time + (new_now.to_f / SEQUENCE.ppqn / SEQUENCE.bpm * 60.0)
37
- if simulated_now > actual_now
38
- sleep(simulated_now - actual_now)
39
- end
40
- end
41
-
42
- @now = new_now
43
- end
44
- end
45
-
46
- # state
47
- SHREDULER = MIDIShreduler.new
48
- SEQUENCE = MIDI::Sequence.new
49
- TRACKS = (1..NUM_TRACKS).map { MIDI::Track.new(SEQUENCE) }
50
- TRACK_DELTAS = TRACKS.map { 0 }
51
- if ALSO_LIVE
52
- MIDI_PLAYER = MIDIator::Interface.new
53
- end
54
-
55
- # midi initialization stuff
56
- TRACKS.each do |track|
57
- SEQUENCE.tracks << track
58
- #track.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))
59
- end
60
- if ALSO_LIVE
61
- MIDI_PLAYER.use :dls_synth
62
- MIDI_PLAYER.instruct_user!
63
- end
64
-
65
- # set up some useful time helpers
66
- module MIDITime
67
- def pulse
68
- self
69
- end
70
- alias_method :pulses, :pulse
71
-
72
- def quarter_note
73
- self * SEQUENCE.ppqn
74
- end
75
- alias_method :quarter_notes, :quarter_note
76
- alias_method :beat, :quarter_note
77
- alias_method :beats, :quarter_note
78
- end
79
-
80
- class Fixnum
81
- include MIDITime
82
- end
83
-
84
- class Float
85
- include MIDITime
86
- end
87
-
88
- # stuff accessible in a shred
89
- module ShredLocal
90
-
91
- def now
92
- SHREDULER.now
93
- end
94
-
95
- def spork(name = "unnamed", &shred)
96
- SHREDULER.spork(name, &shred)
97
- end
98
-
99
- def wait(pulses)
100
- SHREDULER.current_shred.yield(pulses)
101
- end
102
-
103
- def finish
104
- shred = SHREDULER.current_shred
105
- SHREDULER.remove_shred shred
106
- shred.finish
107
- end
108
-
109
- def note_on(note, velocity = 127, channel = 0, track = 0)
110
- TRACKS[track].events << MIDI::NoteOnEvent.new(channel, note, velocity, TRACK_DELTAS[track].to_i)
111
- TRACK_DELTAS[track] = 0
112
- if ALSO_LIVE
113
- MIDI_PLAYER.driver.note_on(note, channel, velocity)
114
- end
115
- end
116
-
117
- def note_off(note, channel = 0, track = 0)
118
- TRACKS[track].events << MIDI::NoteOffEvent.new(channel, note, 0, TRACK_DELTAS[track].to_i)
119
- TRACK_DELTAS[track] = 0
120
- if ALSO_LIVE
121
- MIDI_PLAYER.driver.note_on(note, channel, 0)
122
- end
123
- end
124
-
125
- end
126
-
127
- def save
128
- return if @saved
129
- @saved = true
130
- File.open(MIDI_FILENAME, "wb") { |file| SEQUENCE.write(file) }
131
- end
132
-
133
- FILENAMES.each do |filename|
134
- unless File.readable?(filename)
135
- LOG.fatal "Cannot read file #{filename}"
136
- exit
137
- end
138
- end
139
-
140
- FILENAMES.each do |filename|
141
- SHREDULER.spork(filename) do
142
- include ShredLocal
143
- require filename
144
- end
145
- end
146
-
147
- at_exit { save }
148
-
149
- SHREDULER.run
150
-
151
- save
data/bin/ruck_sleep DELETED
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
-
4
- require "ruck"
5
-
6
- # stuff accessible in a shred
7
- module ShredLocal
8
-
9
- def now
10
- SHREDULER.now
11
- end
12
-
13
- def spork(name = "unnamed", &shred)
14
- SHREDULER.spork(name, &shred)
15
- end
16
-
17
- def wait(seconds)
18
- SHREDULER.current_shred.yield(seconds)
19
- end
20
-
21
- def finish
22
- shred = SHREDULER.current_shred
23
- SHREDULER.remove_shred shred
24
- shred.finish
25
- end
26
-
27
- end
28
-
29
-
30
- SAMPLE_RATE = 1
31
- SHREDULER = Ruck::RealTimeShreduler.new
32
-
33
- filenames = ARGV
34
- filenames.each do |filename|
35
- unless File.readable?(filename)
36
- LOG.fatal "Cannot read file #{filename}"
37
- exit
38
- end
39
- end
40
-
41
- filenames.each do |filename|
42
- SHREDULER.spork(filename) do
43
- include ShredLocal
44
- require filename
45
- end
46
- end
47
- SHREDULER.run
data/bin/ruck_ugen DELETED
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
-
4
- require "ruck"
5
-
6
- # stuff accessible in a shred
7
- module ShredLocal
8
-
9
- def blackhole
10
- BLACKHOLE
11
- end
12
-
13
- def now
14
- SHREDULER.now
15
- end
16
-
17
- def spork(name = "unnamed", &shred)
18
- SHREDULER.spork(name, &shred)
19
- end
20
-
21
- def play(samples)
22
- SHREDULER.current_shred.yield(samples)
23
- end
24
-
25
- def finish
26
- shred = SHREDULER.current_shred
27
- SHREDULER.remove_shred shred
28
- shred.finish
29
- end
30
-
31
- end
32
-
33
-
34
- SAMPLE_RATE = 22050
35
- SHREDULER = Ruck::UGenShreduler.new
36
- BLACKHOLE = Ruck::InChannel.new
37
-
38
- filenames = ARGV
39
- filenames.each do |filename|
40
- unless File.readable?(filename)
41
- LOG.fatal "Cannot read file #{filename}"
42
- exit
43
- end
44
- end
45
-
46
- filenames.each do |filename|
47
- SHREDULER.spork(filename) do
48
- include ShredLocal
49
- include Ruck::Generators
50
- require filename
51
- end
52
- end
53
- SHREDULER.run
@@ -1,28 +0,0 @@
1
-
2
- clear
3
-
4
- spork("framerate watcher") do
5
- start_time = Time.now
6
- frames = 0
7
-
8
- loop do
9
- wait_for_frame
10
- frames += 1
11
- if frames % 100 == 0
12
- puts "#{frames.to_f / (Time.now - start_time)}"
13
- end
14
- end
15
-
16
- end
17
-
18
- loop do
19
- wait 2
20
-
21
- glColor 1, 0, 0
22
- glTranslate(0, 0, -5)
23
- glutSolidCube(2)
24
-
25
- wait 0.1
26
-
27
- clear
28
- end
@@ -1,57 +0,0 @@
1
-
2
- require "rubygems"
3
- require "midiator"
4
-
5
- $midi = MIDIator::Interface.new
6
- $midi.use :dls_synth
7
- $midi.instruct_user!
8
-
9
- def note_on(note, velocity = 127, channel = 0)
10
- $midi.driver.note_on(note, channel, velocity)
11
- end
12
-
13
- def note_off(note, channel = 0)
14
- $midi.driver.note_on(note, channel, 0)
15
- end
16
-
17
- def star_shifter(key)
18
- wait 3
19
- @stars.shift
20
- note_off(key)
21
- end
22
-
23
- spork do
24
- while ev = wait_for_key_down
25
- note_on(ev.key)
26
-
27
- @stars << Star.new
28
- spork { star_shifter ev.key }
29
- end
30
- end
31
-
32
- spork do
33
- while ev = wait_for_key_up
34
- end
35
- end
36
-
37
- class Star
38
- def initialize
39
- @x = rand * 2 - 1
40
- @y = rand * 2 - 1
41
- end
42
-
43
- def draw
44
- glPushMatrix
45
- glTranslate @x, @y, -5
46
- glutSolidCube(0.1)
47
- glPopMatrix
48
- end
49
- end
50
-
51
- clear
52
-
53
- @stars = []
54
- while wait_for_frame
55
- clear
56
- @stars.each { |star| star.draw }
57
- end
@@ -1,9 +0,0 @@
1
-
2
- spork do
3
- loop do
4
- ev = wait_for_key_down
5
- puts "you pressed #{ev.key}"
6
- end
7
- end
8
-
9
- clear
@@ -1,24 +0,0 @@
1
-
2
- def maybe
3
- rand >= 0.5
4
- end
5
-
6
- TRACKS[0].events << MIDI::Controller.new(10, 32, 1) # channel, controller, value
7
- TRACKS[0].events << MIDI::ProgramChange.new(10, 26) # channel, program
8
- MIDI_PLAYER.control_change 32, 10, 1 # number, channel, value
9
- MIDI_PLAYER.program_change 10, 26 # channel, program
10
-
11
- def play(note, dur = 1.quarter_note)
12
- return if maybe
13
- note_on note, 100, 10
14
- wait dur
15
- note_off note, 10
16
- end
17
-
18
- 10.times do
19
- spork { play(rand(30) + 40, rand * 3.quarter_notes + 3.quarter_notes) }
20
- wait 0.5.quarter_note
21
- end
22
-
23
- wait 2.quarter_notes; note_off 0 # end padding
24
-
@@ -1,72 +0,0 @@
1
-
2
- def maybe
3
- rand >= 0.5
4
- end
5
-
6
- @base = 43
7
- @scale = 0
8
- @chord = 0
9
-
10
- major_scale = [0, 2, 4, 5, 7, 9, 11]
11
- minor_scale = [0, 2, 3, 5, 7, 8, 11]
12
- @scales = [major_scale, minor_scale]
13
-
14
- def scale(note, scale)
15
- len = scale.length
16
- oct = note / len
17
- off = note % len
18
- while off < 0
19
- off += len
20
- oct -= 1
21
- end
22
- oct * 12 + scale[off]
23
- end
24
-
25
- def play(note, dur = 1.beat)
26
- midi_note = @base + scale(note, @scales[@scale])
27
- note_on midi_note, 100
28
- wait dur
29
- note_off midi_note
30
- end
31
-
32
- def change_chords
33
- loop do
34
- wait 4.beats
35
- @chord = rand(7)
36
- if rand <= 0.1
37
- @scale = (@scale + 1) % @scales.length
38
- end
39
- end
40
- end
41
-
42
- def play_chord(dur)
43
- spork { play(@chord, dur) }
44
- spork { play(@chord + 2, dur) }
45
- spork { play(@chord + 4, dur) }
46
- end
47
-
48
- def play_chords
49
- loop do
50
- if maybe && maybe
51
- play_chord 2.beats
52
- wait 2.beats
53
- play_chord 2.beats
54
- wait 2.beats
55
- else
56
- play_chord 4.beats
57
- wait 4.beats
58
- end
59
- end
60
- end
61
-
62
- def play_melody
63
- loop do
64
- len = ((rand(2) + 1) / 2.0).beats
65
- play(@chord + 7 + 2 * rand(4), len)
66
- wait len
67
- end
68
- end
69
-
70
- spork { change_chords }
71
- spork { play_chords }
72
- spork { play_melody }
@@ -1,24 +0,0 @@
1
- def beep(wav, chan)
2
- (s = SawOsc.new(:freq => 440, :gain => 0.25)) >> wav.in(chan)
3
- 10.times do
4
- play 0.1.seconds
5
- s.freq *= 1.2
6
- end
7
- s << wav
8
- end
9
-
10
- wav = WavOut.new(:filename => "ex01.wav", :num_channels => 2)
11
- SinOsc.new(:freq => 440, :gain => 0.25) >> wav
12
- SinOsc.new(:freq => 880, :gain => 0.25) >> wav
13
-
14
- wav >> blackhole
15
-
16
- chan = 0
17
-
18
- 10.times do
19
- play 0.7.seconds
20
- chan = (chan + 1) % 2
21
- spork("beep") { beep(wav, chan) }
22
- end
23
-
24
- play 2.seconds
@@ -1,2 +0,0 @@
1
- SinOsc.new(:freq => 440) >> WavOut.new(:filename => "ex02.wav") >> blackhole
2
- play 3.seconds
@@ -1,8 +0,0 @@
1
- wav = WavOut.new(:filename => "ex03.wav")
2
- sin2 = SinOsc.new(:freq => 3)
3
- sin = SinOsc.new(:freq => L{ sin2.last * 220 + 660 },
4
- :gain => L{ 0.5 + sin2.last * 0.5 })
5
-
6
- [sin >> wav, sin2] >> blackhole
7
-
8
- play 3.seconds
@@ -1,14 +0,0 @@
1
- (wav = WavOut.new(:filename => "ex04.wav")) >> blackhole
2
- s = SawOsc.new(:freq => 440, :gain => 0.5)
3
- adsr = ADSR.new(:attack_time => 50.ms,
4
- :attack_gain => 1.0,
5
- :decay_time => 50.ms,
6
- :sustain_gain => 0.5,
7
- :release_time => 1.second)
8
- s >> adsr >> wav
9
-
10
- play 1.second
11
- adsr.on
12
- play 2.seconds
13
- adsr.off
14
- play 2.seconds
@@ -1,9 +0,0 @@
1
- wav = WavIn.new(:filename => "ex01.wav")
2
- wav >> WavOut.new(:filename => "ex05.wav") >> blackhole
3
-
4
- wav.play
5
- play 1.second
6
-
7
- (r = Ramp.new(:from => 1.0, :to => 2.0, :duration => 3.seconds)) >> blackhole
8
- wav.rate = L{ r.last }
9
- play 3.seconds
@@ -1,10 +0,0 @@
1
- # run ex01.rb first
2
-
3
- spoken = WavIn.new(:filename => "ex01.wav")
4
- wav = WavOut.new(:filename => "ex06.wav")
5
- spoken.out(0) >> wav >> blackhole
6
-
7
- (sin = SinOsc.new(:freq => 3, :gain => 0.1)) >> blackhole
8
- spoken.rate = L{ 1.0 + sin.last }
9
-
10
- play spoken.duration
@@ -1,35 +0,0 @@
1
- @bpm = 130.0
2
- @one_beat = (1.0 / @bpm).minutes
3
-
4
- (@wav = WavOut.new(:filename => "ex07.wav")) >> blackhole
5
-
6
- def smash(len = @one_beat)
7
- (n = Noise.new(:gain => 0.4)) >> (a = ADSR.new) >> @wav
8
- a.release_time = len
9
- a.on; play @one_beat / 1.5
10
- a.off; play len
11
- a << @wav
12
- end
13
-
14
- def beat
15
- (thump = SawOsc.new(:freq => 220, :gain => 0.7)) >> (a = ADSR.new) >> @wav
16
- a.on; play @one_beat / 2.0
17
- a.off; play a.release_time
18
- a << @wav
19
- end
20
-
21
- 4.times do
22
- spork("beat 1") { beat }; spork("smash") { smash }
23
- play @one_beat
24
-
25
- spork("beat 2") { beat }
26
- play @one_beat
27
-
28
- spork("beat 3") { beat }
29
- play @one_beat
30
-
31
- spork("beat 4") { beat }
32
- play @one_beat
33
- end
34
-
35
- smash(5.seconds)
@@ -1,28 +0,0 @@
1
- # An experiment with formants
2
- # http://en.wikipedia.org/wiki/Formant
3
-
4
- wav = WavOut.new(:filename => "ex08.wav")
5
- ramps = (1..4).map { Ramp.new(:duration => 50.ms) }
6
- oscillators = (1..4).map { SinOsc.new }
7
- [oscillators >> wav, ramps] >> blackhole
8
-
9
- (0..3).each { |i| oscillators[i].freq = L{ ramps[i].last } }
10
-
11
- #vowel_ah = [1000, 1400]
12
- #vowel_eh = [500, 2300]
13
- #vowel_oh = [500, 1000]
14
- vowel_ee = [[320, 1.0], [2500, 1.0], [3200, 1.0], [4600, 0.6]]
15
- vowel_oo = [[320, 1.0], [800, 0.3], [2500, 0.1], [3300, 0.1]]
16
-
17
- 5.times do
18
- [vowel_ee, vowel_oo].each do |vowel|
19
- puts "doing #{vowel.inspect}"
20
- (0..3).each do |i|
21
- ramps[i].reset
22
- ramps[i].from = ramps[i].to
23
- ramps[i].to = vowel[i].first
24
- oscillators[i].gain = vowel[i].last / 4.0
25
- end
26
- play 1.second
27
- end
28
- end
@@ -1,26 +0,0 @@
1
- # run ex01.rb first (or, preferably, use way better input than ex01.wav)
2
-
3
- =begin
4
- https://lists.cs.princeton.edu/pipermail/chuck-users/2008-May/002983.html
5
-
6
- > One way of subjectively "widening" a stereo image is to do the following:
7
- > feed the left channel back to the right with a short delay, inverted;
8
- > feed the right channel back to the left with a short delay, inverted;
9
- =end
10
-
11
- mix = 0.5
12
-
13
- wavin = WavIn.new :filename => "ex01.wav", :gain => (1.0 - mix)
14
- wavout = WavOut.new :filename => "ex09.wav", :num_channels => 2
15
-
16
- wavin.out(0) >> (delayed_left = Delay.new :time => 10.ms, :gain => mix)
17
- wavin.out(1) >> (delayed_right = Delay.new :time => 10.ms, :gain => mix)
18
- inverted_left = Step.new :value => L{ -delayed_left.next(now) }
19
- inverted_right = Step.new :value => L{ -delayed_right.next(now) }
20
-
21
- wavout >> blackhole
22
- [wavin.out(0), inverted_right] >> wavout.in(0)
23
- [wavin.out(1), inverted_left ] >> wavout.in(1)
24
-
25
- play wavin.duration
26
- puts "processed #{wavin.duration/SAMPLE_RATE} seconds"
@@ -1,15 +0,0 @@
1
- # when run with RealTimeShreduler, illustrates the passage of time
2
-
3
- spork("a") do
4
- loop do
5
- wait 1
6
- puts "second"
7
- end
8
- end
9
-
10
- spork("b") do
11
- loop do
12
- wait 0.5
13
- puts " half-second"
14
- end
15
- end
@@ -1,10 +0,0 @@
1
- # multi-channel WavOut
2
-
3
- s1 = SinOsc.new :freq => 440
4
- s2 = SinOsc.new :freq => 440 * 2
5
- wav = WavOut.new :filename => "ex11.wav", :num_channels => 2
6
- s1 >> wav.in(0)
7
- s2 >> wav.in(1)
8
- wav >> blackhole
9
-
10
- play 3.seconds
@@ -1,9 +0,0 @@
1
- # adds 60 Hz hum to a stereo wav file
2
-
3
- wavin = WavIn.new :filename => "ex11.wav", :gain => 0.5
4
- wavout = WavOut.new :filename => "ex12.wav", :num_channels => 2
5
- wavin >> wavout
6
- SinOsc.new(:freq => 60, :gain => 0.5) >> wavout
7
- wavout >> blackhole
8
-
9
- play 3.seconds
data/lib/ruck/bench.rb DELETED
@@ -1,44 +0,0 @@
1
-
2
- SAMPLE_RATE = 44100
3
-
4
- if ARGV.include? "bench.rb"
5
- # benchmark UGens with shreduling
6
-
7
- TIME = 1.seconds
8
- count = 0
9
- puts "Simulating #{TIME / 1.second} seconds"
10
- loop do
11
- Step.new >> blackhole
12
- count += 1
13
-
14
- start = Time.now
15
- play TIME
16
- time = Time.now - start
17
- puts "#{count}: #{time}"
18
-
19
- break if time > (TIME / 1.second)
20
- end
21
- else
22
- # benchmark UGens without shreduling
23
-
24
- require "ruck"
25
- TIME = 1.seconds
26
- dac = Ruck::InChannel.new
27
- count = 0
28
- @now = 0
29
- puts "Simulating #{TIME / 1.second} seconds"
30
- loop do
31
- Ruck::Generators::Step.new >> dac
32
- count += 1
33
-
34
- start = Time.now
35
- TIME.to_i.times do
36
- dac.next(@now)
37
- @now += 1
38
- end
39
- time = Time.now - start
40
- puts "#{count}: #{time}"
41
-
42
- break if time > (TIME / 1.second)
43
- end
44
- end