Song 1: Random

################################
# Random Song
# Hans Gruendel
# 19.05.2016
#
################################

# Definition of the chord basis used for bass an piano
C_Basis = [60, 72, 84]
F_Basis = [65, 77, 89]
G_Basis = [67, 79, 91]
# List to choose from or to run through
basicTonesOrdered = [C_Basis, F_Basis, G_Basis, C_Basis]

A_Basis = [57, 69, 81]
D_Basis = [62, 74, 86]
# List to choose from or to run through
bridgeTonesOrdered = [A_Basis, D_Basis]

# Sleep duration lists. „0“ means 2 notes are played at the same time
sleepShort = [0, 0, 0.125, 0.125, 0.25, 0.25, 0.375]
sleepMid = [0, 0, 0.125, 0.25, 0.5, 0.75, 1]
sleepLong = [0, 0, 0, 0, 0.25, 0.25, 0.375, 0.75, 1, 2]
sleepExtraLong = [0, 0.75, 1, 1.5, 2]
sleepXXL = [0.25, 0.5,  4, 6, 8, 12]
sleepRegular = [0.25, 0.5]

# Function plays drums in a loop using a sleep list
define :play_drums do |
amplification = 1,    # Amplification factor
n = 64,          # Number of iterations in the loop –> duration the functions runs
sleepList = [0, 1]    # List to choose the duration of sleep from.
|
n.times do
sound = choose([:drum_bass_soft, :drum_heavy_kick]) # The sound is chosen randomly
sample sound, amp: rrand(0.5, 1)* amplification
sleep choose(sleepList)
sound = choose([:drum_cymbal_closed, :drum_cymbal_open])
sample sound, amp: rrand(0.5, 1)* amplification*0.2 # The second „cymbol“ sound is played less loud than the first
sleep choose(sleepList)
end
end

# Function plays bass in a loop using a sleep list
define :play_bass do |
iChordBase = [60, 72, 84],
amplification = 1,  # Amplification factor
n = 64,          # Number of iterations in the loop –> duration the functions runs
sleepList = [0, 1],    # List to choose the duration of sleep from
shift =16           # Shift the tone downwards by this MIDI value
|
use_synth :fm
n.times do
play choose(chord(choose(iChordBase), :major))- shift, amp: amplification, attack: 0.05, release: 0.125, sustain: 0.025, amp: amplification
sleep choose(sleepList)
end
end

# Function plays piano in 2 loops using a sleep list
define :play_piano_loop do|
allChordBase,           # A list of a list of bases to loop through
amplification = 1,    # Amplification factor
n = 64,            # Number of iterations in the loop –> duration the functions runs
sleepList = [0, 1],      # List to choose the duration of sleep from
shift = 16,           # Shift the tone downwards by this MIDI value
key = Major           # Can be one of Sonic Pi’s keys, e.g. Major or Minor
|
use_synth :piano
8. times do |iX|   # outer loop
n.times do
play choose(chord(choose(allChordBase.ring[iX]), key))- shift, amp: amplification # The chord base list is doe into a ring to use it more often
sleep choose(sleepList)
end
end
end

# Function plays piano in a loop using a sleep list
define :play_piano do |
iChordBase = [60, 72, 84],
amplification = 1,  # amplification factor
n = 64,          # number of iterations in the loop –> duration the functions runs
sleepList = [0, 1],    # List to choose the duration of sleep from
shift =16           # Shift the tone downwards by this MIDI value
|
use_synth :piano

n.times do

play choose(chord(choose(iChordBase), :major))- shift, amp: amplification
sleep choose(sleepList)
end
end

# Function plays piano in a loop using a sleep list and an echo effect
define :play_piano_echo do |
iChordBase = [60, 72, 84],
amplification = 1,  # amplification factor
n = 64,          # number of iterations in the loop –> duration the functions runs
sleepList = [0, 1],    # List to choose the duration of sleep from
shift =16           # Shift the tone downwards by this MIDI value
|
use_synth :piano
use_random_seed 1
5.times do |ix|
n.times do
with_fx :echo, max_phase: 4 do
play choose(chord(choose(iChordBase), :major))- shift, amp: amplification + ix * 0.2
end
sleep choose(sleepList)
end
end
end

# Thread runs the intro track
in_thread(name: :S01) do
sync :t0
play_piano_echo basicTonesOrdered[0], 0.3, 200/35, sleepLong, 36
stop
end

# Thread runs the first piano track right hand
in_thread(name: :S11) do
sync :t1
play_piano basicTonesOrdered[0], 1, 100/1.5, sleepShort, 0
stop
end

# Thread runs the first piano track left hand (shift = 24)
in_thread(name: :S12) do
sync :t1
play_piano basicTonesOrdered[0], 1, 100/4, sleepLong, 24
stop
end

# Thread runs the second piano track right hand (shift = 12)
in_thread(name: :S21) do
sync :t2
play_piano basicTonesOrdered[1], 1, 200/1.5, sleepShort, 12
stop
end

# Thread runs the second piano track left hand (shift = 24)
in_thread(name: :S22) do
sync :t2
play_piano basicTonesOrdered[1], 1, 200/4, sleepLong, 24
stop
end

# Thread runs the related bass track
in_thread(name: :S23) do
sync :t2
play_bass basicTonesOrdered[1], 0.25, 200/2, sleepRegular, 36
stop
end

# Thread runs the related drums track
in_thread(name: :S24) do
sync :t2
play_drums 1, 200/3.5, sleepRegular
stop
end

# Thread runs the third track looping through all chords
in_thread(name: :S31) do
sync :t3
play_piano_loop bridgeTonesOrdered, 1, 200/10, sleepShort, 24, :major
stop
end

# Thread runs the related drum track
in_thread(name: :S32) do
sync :t3
play_drums 0.5, 200/3.5, sleepRegular
stop
end

# Thread runs the last piano track right hand (shift = 12)
in_thread(name: :S41) do
sync :t4
4.times do
play_piano_loop basicTonesOrdered, 1, 400/10, sleepShort, 12, :major
stop
end
end

# Thread runs the last piano track left hand (shift = 36)
in_thread(name: :S42) do
sync :t4
4.times do
play_piano_loop basicTonesOrdered, 1, 400/10, sleepShort, 36, :major
stop
end
end

# Thread runs the related bass track
in_thread(name: :S43) do
sync :t4
4.times do
play_bass basicTonesOrdered[0], 0.25, 400/1.2, sleepShort, 36
stop
end
end

# Thread runs the related drum track
in_thread(name: :S44) do
sync :t4
4.times do
play_drums 0.5, 400/6, sleepRegular
stop
end
end

# main loop starts here. It cues the threads and sleeps while they are running

cue :t0
sleep 15
cue :t1
sleep 11
cue :t2
sleep 11*2
cue :t3
sleep 24
cue :t4
sleep 9.5*2