ruck 0.1.2 → 0.2.0

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