/music
Programming + music
I've loved music forever and have tried playing some instruments here and there but only recently started actually making songs after trying the awesome Sonic Pi with the help of Claude Code. These are the finished songs I've made so far.
The following sections have the Ruby code that generates the songs using Sonic Pi.
The following sections have the Ruby code that generates the songs using Sonic Pi.
Programming + music
I've loved music forever and have tried playing some instruments here and there but only recently started actually making songs after trying the awesome Sonic Pi with the help of Claude Code. These are the finished songs I've made so far.
The following sections have the Ruby code that generates the songs using Sonic Pi.
The following sections have the Ruby code that generates the songs using Sonic Pi.
Drifting Loops
# Intro comes from playing with the sleep values of loops. Ending timeline (at 60 BPM, 1 beat = 1 second):
# beat 600 (~10:00) - bells stop, ending begins
# beat 612 (~10:12) - accent stops
# beat 620-636 - slow drone fades out over 16 beats
# beat 636-652 - main guitar + ambient base fade out together
# beat 652-676 - kick plays solo (~24 beats)
# beat 676 - one last kick + last guitar
# vt = virtual time, beats elapsed since this thread started
# Returns 1.0 before fade_start, ramps to 0 over fade_dur beats, then stays at 0
define :calc_fade do |fade_start, fade_dur = 16.0|
return 1.0 if vt <= fade_start
[1.0 - ((vt - fade_start) / fade_dur), 0].max
end
define :reverb_kick do |rate: 1|
with_fx :reverb, room: 1 do
sample :bd_808, amp: 10, rate: rate
end
end
live_loop :guitar_ambient_base do
amp = calc_fade(636)
stop if amp <= 0
sample :guit_e_fifths, rate: -0.5, amp: amp
sleep 12
end
live_loop :soft_kick do
if vt > 676 # final iteration at ~11:16
reverb_kick
sleep 2
sample :guit_e_fifths, rate: -0.5, amp: 0.4 # quiet guitar ghost to end the song
stop
end
reverb_kick
sleep 1
reverb_kick rate: 0.5
sleep 0.5
reverb_kick rate: 0.5
sleep 0.5
end
live_loop :guitar_main do
tick
sleep 12 if look == 0
amp = calc_fade(636)
stop if amp <= 0
if look.even?
sample :guit_e_fifths, rate: 1, amp: amp
else
with_fx :echo, mix: 1, phase: 0.25, decay: 4 do
sample :guit_e_fifths, rate: 1, amp: amp
end
end
sleep 6
sample :guit_e_fifths, rate: 1, amp: amp
sleep 6
sample :guit_e_fifths, rate: 0.9, amp: amp
sleep 3
end
live_loop :guitar_accent do
tick
stop if vt > 612 # stop at ~10:12
if look == 0
sleep 25 # first time
sample :guit_e_fifths, rate: 1.6
elsif look % 3 == 0
sleep 4 # sync with guitar_main like the first time
sample :guit_e_fifths, rate: 1.5 # listener expects 1.6
else
sleep 13 # every time after
sample :guit_e_fifths, rate: rrand(1.6, 2)
end
end
live_loop :guitar_slow_drone do
tick
sleep(look == 0 ? 27 : 15)
amp = calc_fade(620)
stop if amp <= 0
sample :guit_e_fifths, rate: 0.3, amp: amp
end
live_loop :haunted_random_bells do
stop if vt > 600 # first to go, stops at ~10:00
sleep 15
sample :perc_bell, amp: 0.5, rate: rrand(-0.5, 0.5)
end
Haunted Glitch Heaven
use_random_seed 1337
switchup_A = 120
stop_toggle_A = 220
set :kick_final_played, false
set :kick_B_final_played, false
set :lunar_ending_played, false
set :accent2_active, false
live_loop :robot_signifier do
sleep 40
stop if vt > stop_toggle_A + 10
with_fx :reverb, room: 1 do
with_fx :lpf, cutoff: 80 do
sample :glitch_robot2
end
end
end
# -- intro blips A --
16.times do
sample :elec_blip, rate: rrand(0.5, 2)
sleep 0.125
end
sleep 1
define :beep_collection do
ring(
:elec_blip2,
:elec_beep,
:elec_bong,
:elec_filt_snare,
:elec_flip,
:elec_hollow_kick,
:elec_mid_snare,
:elec_ping,
:elec_plip,
:elec_soft_kick,
:elec_tick,
:elec_twang,
:elec_twip
)
end
live_loop :kick do
if vt > stop_toggle_A
unless get[:kick_final_played]
set :kick_final_played, true
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.5, amp: 0.5
end
with_fx :echo, mix: 1, phase: 0.5, decay: 8 do
sample :bd_haus, rate: 0.5, amp: 0.5
end
sleep 0.5
else
stop if vt > stop_toggle_A + 31
with_fx :lpf, cutoff: 80 do
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.35, amp: 0.2
end
end
sleep 0.5
end
else
tick
if look < 40
set :kick_rate, 0.8
elsif look % 40 == 0
set :kick_rate, vt >= switchup_A ? rrand(0.3, 0.6) : rrand(0.6, 0.9)
end
sample :bd_haus, rate: get[:kick_rate], amp: 0.6
sleep 0.5
end
end
live_loop :glitchy_beeps_barrage do
stop if vt > stop_toggle_A
tick
sleep 8 if look == 0
if vt < 20
base_amp = 0.4
ramp_amp = [base_amp * ((vt - 10.0) / 10.0), 0].max
else
ramp_amp = 0.4
end
run = look / 8
s = if vt >= switchup_A and look.odd?
beep_collection.tick(:phone_other)
elsif vt >= 80 and run.odd?
beep_collection[run / 2]
else
:elec_blip
end
sample s, rate: [1, 1, 1, 1, 0.5].choose, pan: [-1, 1].tick("pan_#{s}"), amp: ramp_amp
sleep 0.25
end
live_loop :glitchy_beeps_main_burst do
stop if vt > stop_toggle_A
tick
mod = look >= 20 ? 21 : 5
if look % mod == 0 and look != 21
burst = tick(:burst)
s = if get[:accent2_active]
burst.even? ? :elec_blip : beep_collection.tick(:other)
else
:elec_blip
end
8.times do
sample s, rate: rrand(0.5, 2), amp: 0.5
sleep 0.125
end
else
sleep 0.25
end
end
live_loop :drone do
stop if vt > stop_toggle_A + 10
sleep 20
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
r = vt >= switchup_A ? rrand(0.2, 0.4) : rrand(0.4, 0.9)
sample :ambi_drone, rate: r, amp: 0.2
end
end
end
live_loop :glitch_blam do
stop if vt > stop_toggle_A + 15
sleep 40
with_fx :reverb, room: 1 do
r = vt >= switchup_A ? rrand(0.65, 0.75) : rrand(0.75, 0.85)
sample (ring :glitch_bass_g, :glitch_perc3).tick, rate: r, amp: 0.5
end
end
live_loop :dark_ambient_rush do
stop if vt > stop_toggle_A + 5
tick(:iter)
sleep(look(:iter) == 0 ? 40 : 20)
set :accent2_active, true
with_fx :reverb, room: 1 do
samps = vt >= switchup_A ? (ring :ambi_dark_woosh, :ambi_lunar_land) : (ring :loop_drone_g_97, :loop_3d_printer)
sample samps.tick, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
live_loop :creepy_choir do
stop if vt > stop_toggle_A + 10
tick
sleep(look == 0 ? 55 : 15)
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
r = vt >= switchup_A ? rrand(0.3, 0.6) : rrand(0.6, 0.9)
sample :ambi_choir, rate: r, amp: 0.4
end
end
end
# ========================================================================================
# PART B
# ========================================================================================
in_thread do
sleep stop_toggle_A + 30 - 1
switchup_B = 20
stop_toggle_B = 470
define :main_burst_B do |s, amps|
8.times do
sample s, rate: rrand(0.5, 2), amp: amps[0]
sleep 0.125
end
sleep 1
8.times do
sample s, rate: rrand(0.5, 1), amp: amps[1]
sleep 0.125
end
sleep 1
with_fx :echo, mix: 1, phase: 0.25, decay: 4 do
8.times do
sample s, rate: rrand(0.5, 2), amp: amps[2]
sleep 0.125
end
end
sleep 1
with_fx :echo, mix: 1, phase: 0.25, decay: 4 do
8.times do
sample s, rate: rrand(0.1, 0.5), amp: amps[3]
sleep 0.125
end
end
sleep 1
end
# -- intro blips B (takes 8 beats) --
main_burst_B :elec_blip, [0.8, 0.8, 1, 0.5]
b_start = vt # try to have a 0 reference point once part B starts
live_loop :robot_signifier_B do
stop if vt > stop_toggle_B - 5
sleep(tick == 0 ? switchup_B : 40)
with_fx :reverb, room: 1 do
with_fx :lpf, cutoff: 80 do
sample :glitch_robot2
end
end
end
live_loop :glitchy_beeps_main_burst_B do
stop if vt > stop_toggle_B + 8
b_vt = vt - b_start
if b_vt >= switchup_B && b_vt < switchup_B + 18
sleep 1
next
end
s = b_vt > switchup_B ? beep_collection.tick(:other) : :elec_blip
main_burst_B s, [0.4, 0.4, 0.5, 0.3]
end
live_loop :kick_B do
b_vt = vt - b_start
if vt > stop_toggle_B
unless get[:kick_B_final_played]
set :kick_B_final_played, true
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.5, amp: 0.4
end
with_fx :echo, mix: 1, phase: 0.5, decay: 8 do
sample :bd_haus, rate: 0.5, amp: 0.4
end
sleep 0.5
else
fade_dur = 16.0
elapsed = vt - stop_toggle_B
stop if elapsed > fade_dur
fade_amp = 0.2 * (1.0 - (elapsed / fade_dur))
# trigger lunar landing once at the start of the trailing kicks
unless get[:lunar_ending_played]
set :lunar_ending_played, true
with_fx :reverb, room: 1 do
sample :ambi_lunar_land, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
with_fx :lpf, cutoff: 80 do
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.35, amp: fade_amp
end
end
sleep 0.5
end
else
# drop out for a beat then 3 rapid kicks every 40 beats (synced to robot_signifier_B)
cycle = b_vt >= switchup_B ? (b_vt - switchup_B) % 40 : nil
if cycle && cycle < 1
sleep 0.5
elsif cycle && cycle >= 1 && cycle < 1.75
with_fx :reverb, room: 0.8 do
sample :bd_haus, rate: 0.3, amp: 0.6
end
sleep 0.25
else
tick
if look < 40
set :kick_B_rate, 0.6
elsif look % 40 == 0
set :kick_B_rate, rrand(0.4, 0.6)
end
with_fx :reverb, room: 0.8 do
sample :bd_haus, rate: get[:kick_B_rate], amp: 0.6
end
sleep 0.5
end
end
end
live_loop :drone_B do
stop if vt > stop_toggle_B - 3
tick
sleep switchup_B + 2
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
sample :ambi_drone, rate: rrand(0.2, 0.4), amp: 0.2
end
end
end
live_loop :glitch_blam_B do
stop if vt > stop_toggle_B - 6
tick
sleep switchup_B
with_fx :reverb, room: 1 do
sample (ring :tbd_highkey_c4, :glitch_perc3).look, rate: rrand(0.65, 0.75), amp: 0.8
end
end
live_loop :creepy_choir_B do
stop if vt > stop_toggle_B - 2
tick
sleep(look == 0 ? 30 : 15)
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
sample :ambi_choir, rate: rrand(0.8, 0.9), amp: 0.8
end
end
end
live_loop :dark_ambient_rush_B do
stop if vt > stop_toggle_B - 4
tick
sleep 40
with_fx :reverb, room: 1 do
sample (ring :ambi_dark_woosh, :tbd_fxbed_loop).look, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
live_loop :glitchy_beeps_barrage_B do
stop if vt > stop_toggle_B - 10
tick(:init)
sleep switchup_B if look(:init) == 0
tick
run = look / 8
s = if look.odd?
beep_collection.tick(:phone_other)
elsif run.odd?
beep_collection[run / 2]
else
:elec_blip
end
sample s, rate: [1, 1, 1, 1, 0.5].choose, pan: [-1, 1].tick("pan_#{s}"), amp: 0.6
sleep 0.25
end
endHaunted Glitch Heaven
use_random_seed 1337
switchup_A = 120
stop_toggle_A = 220
set :kick_final_played, false
set :kick_B_final_played, false
set :lunar_ending_played, false
set :accent2_active, false
live_loop :robot_signifier do
sleep 40
stop if vt > stop_toggle_A + 10
with_fx :reverb, room: 1 do
with_fx :lpf, cutoff: 80 do
sample :glitch_robot2
end
end
end
# -- intro blips A --
16.times do
sample :elec_blip, rate: rrand(0.5, 2)
sleep 0.125
end
sleep 1
define :beep_collection do
ring(
:elec_blip2,
:elec_beep,
:elec_bong,
:elec_filt_snare,
:elec_flip,
:elec_hollow_kick,
:elec_mid_snare,
:elec_ping,
:elec_plip,
:elec_soft_kick,
:elec_tick,
:elec_twang,
:elec_twip
)
end
live_loop :kick do
if vt > stop_toggle_A
unless get[:kick_final_played]
set :kick_final_played, true
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.5, amp: 0.5
end
with_fx :echo, mix: 1, phase: 0.5, decay: 8 do
sample :bd_haus, rate: 0.5, amp: 0.5
end
sleep 0.5
else
stop if vt > stop_toggle_A + 31
with_fx :lpf, cutoff: 80 do
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.35, amp: 0.2
end
end
sleep 0.5
end
else
tick
if look < 40
set :kick_rate, 0.8
elsif look % 40 == 0
set :kick_rate, vt >= switchup_A ? rrand(0.3, 0.6) : rrand(0.6, 0.9)
end
sample :bd_haus, rate: get[:kick_rate], amp: 0.6
sleep 0.5
end
end
live_loop :glitchy_beeps_barrage do
stop if vt > stop_toggle_A
tick
sleep 8 if look == 0
if vt < 20
base_amp = 0.4
ramp_amp = [base_amp * ((vt - 10.0) / 10.0), 0].max
else
ramp_amp = 0.4
end
run = look / 8
s = if vt >= switchup_A and look.odd?
beep_collection.tick(:phone_other)
elsif vt >= 80 and run.odd?
beep_collection[run / 2]
else
:elec_blip
end
sample s, rate: [1, 1, 1, 1, 0.5].choose, pan: [-1, 1].tick("pan_#{s}"), amp: ramp_amp
sleep 0.25
end
live_loop :glitchy_beeps_main_burst do
stop if vt > stop_toggle_A
tick
mod = look >= 20 ? 21 : 5
if look % mod == 0 and look != 21
burst = tick(:burst)
s = if get[:accent2_active]
burst.even? ? :elec_blip : beep_collection.tick(:other)
else
:elec_blip
end
8.times do
sample s, rate: rrand(0.5, 2), amp: 0.5
sleep 0.125
end
else
sleep 0.25
end
end
live_loop :drone do
stop if vt > stop_toggle_A + 10
sleep 20
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
r = vt >= switchup_A ? rrand(0.2, 0.4) : rrand(0.4, 0.9)
sample :ambi_drone, rate: r, amp: 0.2
end
end
end
live_loop :glitch_blam do
stop if vt > stop_toggle_A + 15
sleep 40
with_fx :reverb, room: 1 do
r = vt >= switchup_A ? rrand(0.65, 0.75) : rrand(0.75, 0.85)
sample (ring :glitch_bass_g, :glitch_perc3).tick, rate: r, amp: 0.5
end
end
live_loop :dark_ambient_rush do
stop if vt > stop_toggle_A + 5
tick(:iter)
sleep(look(:iter) == 0 ? 40 : 20)
set :accent2_active, true
with_fx :reverb, room: 1 do
samps = vt >= switchup_A ? (ring :ambi_dark_woosh, :ambi_lunar_land) : (ring :loop_drone_g_97, :loop_3d_printer)
sample samps.tick, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
live_loop :creepy_choir do
stop if vt > stop_toggle_A + 10
tick
sleep(look == 0 ? 55 : 15)
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
r = vt >= switchup_A ? rrand(0.3, 0.6) : rrand(0.6, 0.9)
sample :ambi_choir, rate: r, amp: 0.4
end
end
end
# ========================================================================================
# PART B
# ========================================================================================
in_thread do
sleep stop_toggle_A + 30 - 1
switchup_B = 20
stop_toggle_B = 470
define :main_burst_B do |s, amps|
8.times do
sample s, rate: rrand(0.5, 2), amp: amps[0]
sleep 0.125
end
sleep 1
8.times do
sample s, rate: rrand(0.5, 1), amp: amps[1]
sleep 0.125
end
sleep 1
with_fx :echo, mix: 1, phase: 0.25, decay: 4 do
8.times do
sample s, rate: rrand(0.5, 2), amp: amps[2]
sleep 0.125
end
end
sleep 1
with_fx :echo, mix: 1, phase: 0.25, decay: 4 do
8.times do
sample s, rate: rrand(0.1, 0.5), amp: amps[3]
sleep 0.125
end
end
sleep 1
end
# -- intro blips B (takes 8 beats) --
main_burst_B :elec_blip, [0.8, 0.8, 1, 0.5]
b_start = vt # try to have a 0 reference point once part B starts
live_loop :robot_signifier_B do
stop if vt > stop_toggle_B - 5
sleep(tick == 0 ? switchup_B : 40)
with_fx :reverb, room: 1 do
with_fx :lpf, cutoff: 80 do
sample :glitch_robot2
end
end
end
live_loop :glitchy_beeps_main_burst_B do
stop if vt > stop_toggle_B + 8
b_vt = vt - b_start
if b_vt >= switchup_B && b_vt < switchup_B + 18
sleep 1
next
end
s = b_vt > switchup_B ? beep_collection.tick(:other) : :elec_blip
main_burst_B s, [0.4, 0.4, 0.5, 0.3]
end
live_loop :kick_B do
b_vt = vt - b_start
if vt > stop_toggle_B
unless get[:kick_B_final_played]
set :kick_B_final_played, true
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.5, amp: 0.4
end
with_fx :echo, mix: 1, phase: 0.5, decay: 8 do
sample :bd_haus, rate: 0.5, amp: 0.4
end
sleep 0.5
else
fade_dur = 16.0
elapsed = vt - stop_toggle_B
stop if elapsed > fade_dur
fade_amp = 0.2 * (1.0 - (elapsed / fade_dur))
# trigger lunar landing once at the start of the trailing kicks
unless get[:lunar_ending_played]
set :lunar_ending_played, true
with_fx :reverb, room: 1 do
sample :ambi_lunar_land, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
with_fx :lpf, cutoff: 80 do
with_fx :reverb, room: 1 do
sample :bd_haus, rate: 0.35, amp: fade_amp
end
end
sleep 0.5
end
else
# drop out for a beat then 3 rapid kicks every 40 beats (synced to robot_signifier_B)
cycle = b_vt >= switchup_B ? (b_vt - switchup_B) % 40 : nil
if cycle && cycle < 1
sleep 0.5
elsif cycle && cycle >= 1 && cycle < 1.75
with_fx :reverb, room: 0.8 do
sample :bd_haus, rate: 0.3, amp: 0.6
end
sleep 0.25
else
tick
if look < 40
set :kick_B_rate, 0.6
elsif look % 40 == 0
set :kick_B_rate, rrand(0.4, 0.6)
end
with_fx :reverb, room: 0.8 do
sample :bd_haus, rate: get[:kick_B_rate], amp: 0.6
end
sleep 0.5
end
end
end
live_loop :drone_B do
stop if vt > stop_toggle_B - 3
tick
sleep switchup_B + 2
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
sample :ambi_drone, rate: rrand(0.2, 0.4), amp: 0.2
end
end
end
live_loop :glitch_blam_B do
stop if vt > stop_toggle_B - 6
tick
sleep switchup_B
with_fx :reverb, room: 1 do
sample (ring :tbd_highkey_c4, :glitch_perc3).look, rate: rrand(0.65, 0.75), amp: 0.8
end
end
live_loop :creepy_choir_B do
stop if vt > stop_toggle_B - 2
tick
sleep(look == 0 ? 30 : 15)
with_fx :reverb, room: 1 do
with_fx :echo, phase: 1, decay: 10 do
sample :ambi_choir, rate: rrand(0.8, 0.9), amp: 0.8
end
end
end
live_loop :dark_ambient_rush_B do
stop if vt > stop_toggle_B - 4
tick
sleep 40
with_fx :reverb, room: 1 do
sample (ring :ambi_dark_woosh, :tbd_fxbed_loop).look, pitch_stretch: 12, attack: 4, sustain: 4, release: 4
end
end
live_loop :glitchy_beeps_barrage_B do
stop if vt > stop_toggle_B - 10
tick(:init)
sleep switchup_B if look(:init) == 0
tick
run = look / 8
s = if look.odd?
beep_collection.tick(:phone_other)
elsif run.odd?
beep_collection[run / 2]
else
:elec_blip
end
sample s, rate: [1, 1, 1, 1, 0.5].choose, pan: [-1, 1].tick("pan_#{s}"), amp: 0.6
sleep 0.25
end
end