Using the concept of state machines (thanks to @nabisco) on polyphonic lines, this resembles some stuff I heard Gamelan ensembles play.
Due to the changing random seed, this will sound different each time you execute the code.
#MarkovChains Freequencies
t = Time.now.to_i
use_random_seed t
puts rand
live_loop :temp do
set :temp, 52
sleep 10
end
#Setting the range of possible pitches, in this case one octave
set :min_pitch, 66
set :max_pitch, 78
#Setting the pitches to be used; not quantized to any kind of scale so microtonality or strange constellations may come up
set :eins, rrand(get[:min_pitch], get[:max_pitch])
set :zwei, rrand(get[:min_pitch], get[:max_pitch])
set :drei, rrand(get[:min_pitch], get[:max_pitch])
set :vier, rrand(get[:min_pitch], get[:max_pitch])
set :fünf, rrand(get[:min_pitch], get[:max_pitch])
#Setting the rhythmic values to be used
RHYTHMIC_VALUES = [0.125, 0.25, 0.375, 0.5, 0.75, 1, 1.5].pick(6)
#initial state
set :current_state, 0
#Setting the actual notes to be used; in this case, the fifth note is omitted while the first and third each occur twice
NOTES = [get[:eins], get[:zwei], get[:drei], get[:vier], get[:drei], get[:eins]]
#Multiplying the rhythmic values to achieve different rhythmic levels - not sure if this actually works?!
live_loop :rhythm do
INTERONSET = (RHYTHMIC_VALUES * (ring 1, 2, 3, 4, 6, 8).choose)
sleep rrand_i(4, 64)
end
# State machine rules
RULES = {
0 => [1],
1 => [2],
2 => [3, 3, 0],
3 => [1, 2, 4, 4],
4 => [5, 0],
5 => [1]
}
#Setting a value for transposition of the sequence of notes resulting from the state machine rules
#Due to the four zeros, no transposition is most likely
live_loop :trnsp do
set :transpose, [-12, 0, 0, 0, 0, 12].choose
sleep rrand_i(4, 64)
end
with_fx :reverb, mix: 0.2 do
live_loop :update_state do
# get current state value -- 0 on the first run
use_bpm get[:temp]
s = get[:current_state]
play NOTES[s] + get[:transpose], amp: rrand(0.2, 0.8), release: rrand(0.1, 0.5), pan: rrand(-1, 1)
sleep INTERONSET[s]
# update to next state
set :current_state, RULES[s].choose
end
#Setting a different value for transposition of the second voice
live_loop :trnsp1 do
set :transpose1, [-12, 0, 0, 0, 12].choose
sleep rrand_i(4, 64)
end
#initial state for the second voice
set :current_state1, 0
#As above
live_loop :rhythm1 do
INTERONSET1 = (RHYTHMIC_VALUES * (ring 1, 2, 3, 4, 6, 8).choose)
sleep rrand_i(4, 64)
end
live_loop :update_state1 do
# get current state value for second voice -- 0 on the first run
use_bpm get[:temp]
s = get[:current_state1]
play NOTES[s] + get[:transpose1], amp: rrand(0.2, 0.8), release: rrand(0.1, 0.5), pan: rrand(-1, 1)
sleep INTERONSET1[s]
# update to next state for second voice
set :current_state1, RULES[s].choose
end
#and the same for a third voice...
live_loop :trnsp2 do
set :transpose2, [-12, 0, 0, 0, 12].choose
sleep rrand_i(4, 64)
end
set :current_state2, 0
live_loop :rhythm2 do
INTERONSET2 = (RHYTHMIC_VALUES * (ring 1, 2, 3, 4, 6, 8).choose)
sleep rrand_i(4, 64)
end
live_loop :update_state2 do
use_bpm get[:temp]
s = get[:current_state2]
play NOTES[s] + get[:transpose2], amp: rrand(0.2, 0.8), release: rrand(0.1, 0.5), pan: rrand(-1, 1)
sleep INTERONSET2[s]
set :current_state2, RULES[s].choose
end
end