Skip to content

Instantly share code, notes, and snippets.

@WindowDump
Last active May 11, 2023 23:16
Show Gist options
  • Save WindowDump/d599ac233b8e543181bf9d298f0a722c to your computer and use it in GitHub Desktop.
Save WindowDump/d599ac233b8e543181bf9d298f0a722c to your computer and use it in GitHub Desktop.
sonic pi tune based around randomized melody and amen break slices
# cold snap, coded by window dump
use_bpm 128
set_volume! 0.5
define :pattern do |pattern|
return pattern.ring.tick == "x"
end
define :set_chord_main do
chrds = []
chrds.append(degree(:iv, :e2, :minor_pentatonic))
chrds.append(degree(:iii, :e2, :minor_pentatonic))
chrds.append(degree(:v, :e2, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
chrds.append(degree(:ii, :e2, :minor_pentatonic))
chrds.append(degree(:iii, :e2, :minor_pentatonic))
chrds.append(degree(:v, :e1, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
set :chord, chrds.ring.tick(:chord_heartbeat)
end
define :set_chord_verse do
chrds = []
chrds.append(degree(:i, :e2, :minor_pentatonic))
chrds.append(degree(:ii, :e2, :minor_pentatonic))
chrds.append(degree(:iv, :e1, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
chrds.append(degree(:iii, :e2, :minor_pentatonic))
chrds.append(degree(:v, :e1, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
set :chord, chrds.ring.tick(:chord_heartbeat)
end
define :set_chord_low do
chrds = []
chrds.append(degree(:iv, :e1, :minor_pentatonic))
chrds.append(degree(:iii, :e1, :minor_pentatonic))
chrds.append(degree(:v, :e1, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
chrds.append(degree(:ii, :e2, :minor_pentatonic))
chrds.append(degree(:iv, :e1, :minor_pentatonic))
chrds.append(degree(:v, :e1, :minor_pentatonic))
chrds.append(degree(:i, :e2, :minor_pentatonic))
set :chord, chrds.ring.tick(:chord_heartbeat)
end
define :set_chord_high do
chrds = []
chrds.append(degree(:iv, :e2, :minor_pentatonic))
chrds.append(degree(:iii, :e2, :minor_pentatonic))
chrds.append(degree(:v, :e2, :minor_pentatonic))
chrds.append(degree(:i, :e3, :minor_pentatonic))
chrds.append(degree(:iv, :e2, :minor_pentatonic))
chrds.append(degree(:v, :e2, :minor_pentatonic))
chrds.append(degree(:iii, :e2, :minor_pentatonic))
chrds.append(degree(:ii, :e2, :minor_pentatonic))
set :chord, chrds.ring.tick(:chord_heartbeat)
end
live_loop :heartbeat, delay: 0.1 do
set_chord_main
##| set_chord_verse
##| set_chord_low
##| set_chord_high
##| set :chord, ring(degree(:i, :e2, :minor_pentatonic), degree(:v, :e1, :minor_pentatonic)).tick(:chord_heartbeat)
vibe = knit(false, 8, true, 6, false, 2).tick(:vibe_on)
# mixer
bass_amp = 0.75
kick_amp = 0.50
snare_amp = 0.23
ride_amp = 0.11
amen_amp = 0.4 * 0.75
melody_amp = 0.48
acid_amp = 0.13
pad_amp = 0.80
global_sc = 0.5
melody_sc = global_sc * 0.8
if knit(true, 3, false, 1).tick(:fill) or vibe
kick_pat = 'x-x-x-x-x-x-x-x-'
kick_full_pat = 'x---x---x---x---'
snare_pat = '--x---x---x---x-'
ride_pat = (vibe or one_in(2)) ? "x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-" : "x-x-x-x-x-x-x-x-x-xxx-x-x-xxx-x-"
bass_len = 7.25
else
if one_in(2)
kick_pat = 'x-x-x-x-x-x-x--x'
kick_full_pat = 'x---x---x---x--x'
snare_pat = '--x---x---x--xx-'
ride_pat = "x-x-x-x-x-x-x-x-x-xxx-x-x-xx--x-"
bass_len = 6.5
else
kick_pat = 'x-x-x-x-x-x-x-xx'
kick_full_pat = 'x---x---x-x-x-x-'
snare_pat = '--x---x-x-x-xxxx'
ride_pat = "x-x-x-x-x-x-x-x-x-x-x-x-xxxxxxxx"
snare_amp *= 1.1
bass_len = 7.25
end
end
pad_args = {amp: pad_amp, sc: global_sc * 0.75, note: get[:chord] + 24}
amen_args_bar1 = {amp: amen_amp, seed: rrand_i(0, 1000), kick: true, rev: vibe, full: true, slices: 32, bc_sr: 11025}
amen_b1_clean = knit(true, 4, false, 4).tick(:amen1_clean)
amen_args_bar1[:bar1_clean] = vibe ? false : amen_b1_clean
amen_args_bar1[:s_arr] = ring(0,1,0,3,4,5,6,7,8,8,9,9,12,13,60,61) # for 64 slices
amen32_snares = [2,6,10,14,18,23,26,30]
amen32_chop_splash = ring(0,0,amen32_snares.choose,3,4,4,amen32_snares.choose,29)
amen32_chop_bar2 = ring(8,8,amen32_snares.choose,13,12,11,amen32_snares.choose,amen32_snares.choose)
amen_args_bar1[:s_arr] = (vibe or one_in(2)) ? nil : one_in(2) ? amen32_chop_splash : amen32_chop_bar2 # for 32 slices
melody_bar1 = {dt1: line(0.1, 0.2, steps: 32).tick(:m1_dt1), dt2: line(0.1, 0.5, steps: 64).tick(:m1_dt2), amp2: 0.25, pitch2: 7, amp: melody_amp, sc: melody_sc, seed: vibe ? rrand_i(3001, 4000) :rrand_i(1337, 1344)}
tb303_args = {amp: acid_amp, sc: global_sc, pattern: '---x---x', notes: ring(get[:chord], get[:chord] + 5)}
tb303_args[:var] = (one_in(3) or vibe) ? knit(0, 8, -12, 4, 12, 2).pick(3) : knit(0, 4, 10, 4, 7, 4, 5, 4)
amen_args_bar2 = {amp: amen_amp, seed: rrand_i(0, 1000), full: false, rev: true, bar: range(0, 3).tick(:amen_bar)}
amen_args_bar2[:bc_sr] = 11025 #knit(11025, 4, 22050, 1, 5512, 2, 2756, 1).choose
amen_args_bar2[:bc_bits] = 8#range(5, 9).choose
#amen_args_bar1[:slices] = 8
#amen_args_bar1[:kick] = false
amen_args_bar1[:s_arr] = (vibe or one_in(2)) ? nil : one_in(2) ? amen32_chop_splash : amen32_chop_bar2 # for 32 slices
melody_bar2 = {dt1: line(0.1, 0.3, steps: 128).tick(:m2_dt1), dt2: line(0.2, 0.6, steps: 64).tick(:m2_dt2), amp2: 0.25, pitch2: vibe ? 7 : 12, amp: melody_amp, sc: melody_sc, seed: vibe ? rrand_i(2000, 3000) : 4923}
# triggers
set :melody_surf, melody_bar1
set :kicks, {amp: kick_amp, pattern: kick_pat, full: kick_full_pat}
set :drum_snare, {amp: snare_amp, pattern: snare_pat}
set :drum_ride, {amp: ride_amp, sc: global_sc, pattern: ride_pat}
set :amen_chaos, amen_args_bar1
##| pad_note = get[:chord] + 24#(get[:chord] < 52 ? 29 : 24)
if ring(true, false).tick(:bass_full) or one_in(4) or vibe
set :bass_pad, {note: get[:chord], amp: bass_amp, len: bass_len, sc: global_sc}
set :pad_synth, pad_args.merge(sus: 7.0)
bass_full = true
else
set :bass_pad, {note: get[:chord], amp: bass_amp, len: 3, sc: global_sc}
set :pad_synth, pad_args.merge(sus: 3.5)
bass_full = false
end
set :tb303_pad, tb303_args.merge(pattern: vibe ? knit('--', 4, '-x', 1, 'x-', 1).repeat(4).pick(8).join() : '---x---x---x---x')
##| set :tb303_pad, tb303_args.merge(var: knit(0, 4, 10, 4))
##| set :tb303_pad, tb303_args.merge(var: ring(0))
sleep 4.0
set :melody_surf, melody_bar2
##| set :tb303_pad, tb303_args.merge(var: knit(7, 4, 5, 4))
##| set :tb303_pad, tb303_args.merge(var: ring(0))
##| set :amen_chaos, amen_args_bar1.merge(bar1_clean: true)
##| set :amen_chaos, amen_args_bar1
set :amen_chaos, amen_args_bar2
if bass_full
sleep 4.0
else
set :pad_synth, pad_args.merge(sus: 3.0, note: get[:chord] + [29, 24].choose)
if one_in(2)
set :bass_pad, {note: get[:chord] - 2, amp: bass_amp, len: 0.75, sc: global_sc}
sleep 2.0
set :bass_pad, {note: get[:chord] + 5, amp: bass_amp, len: 0.5, sc: global_sc}
sleep 2.0
else
set :bass_pad, {note: get[:chord] + [3, 5, 7].choose, amp: bass_amp, len: 2.75, sc: global_sc}
sleep 4.0
end
end
end
live_loop :rand_surfer do
args = sync :melody_surf
use_random_seed args.fetch(:seed, rrand_i(1337, 1344))
tick_reset_all
use_synth :dsaw
use_synth_defaults release: 0.2
dt1 = args.fetch(:dt1, 0.2)
dt2 = args.fetch(:dt2, 0.4)
notes = scale(get[:chord], :minor_pentatonic, num_octaves: 2)
panning = line(-0.1, 0.1, steps: 8).mirror
with_fx :slicer, phase: 1.0, invert_wave: true, wave: 1, pulse_width: 0.05, smooth_up: 0.3, smooth_down: 0.01, mix: args.fetch(:sc, 0.9) do
with_fx :reverb, amp: args.fetch(:amp, 0.5), mix: 0.3, damp: 0.3, room: 0.8 do
with_fx :echo, mix: 1.0, pre_mix: 0.5, phase: 0.75, decay: 4, max_phase: 8.0, reps: 16 do
note = notes.choose
play note, amp: args.fetch(:amp1, 1.0), cutoff: rrand(70, 120), detune: (dt1 == 0 ? 0 : rrand(dt1 - 0.1, dt1 + 0.1))
play note + args.fetch(:pitch2, 12), amp: args.fetch(:amp2, 0.15), cutoff: rrand(90, 131), pan: panning.tick(:pan_2), detune: (dt2 == 0 ? 0 : rrand(dt2 - 0.1, dt2 + 0.1)) if args[:amp2] != nil
##| play note - 12, amp: args.fetch(:amp2, 0.15) * 0.4, cutoff: rrand(60, 80), pan: panning.look(:pan_2), detune: (dt2 == 0 ? 0 : rrand(dt2 - 0.1, dt2 + 0.1)) if args[:amp2] != nil
sleep 0.25 if knit(true, 15, false, 1).tick(:skip_last)
end
end
end
end
live_loop :trance_kick do
args = sync :kicks
pat = args.fetch(:pattern, 'x-x-x-x-x-x-x-x-')
full_pat = args.fetch(:full, 'x---x---x---x---').ring
len = pat.size
tick_reset_all
with_fx :distortion, reps: len, amp: args.fetch(:amp, 0.5), pre_amp: 1.5, distort: 0.5 do
full = full_pat.tick(:full) == "x"
if pattern pat
sample :bd_ada, sustain: (full ? 1.0 : 0), release: 0.1
hydra "speed = 0.5"
else
hydra "speed = 0.1"
end
sleep 0.5 if knit(true, len - 1, false, 1).tick(:skip_last)
end
end
live_loop :bass_pad do
args = sync :bass_pad
note = args.fetch(:note, get[:chord])
len = args.fetch(:len, 8.0)
use_synth_defaults attack: 0.5, decay: 0.25, sustain_level: 0.8, sustain: len, release: 1.0
with_fx :slicer, phase: 1.0, invert_wave: true, wave: 1, pulse_width: 0.05, smooth_up: 0.2, smooth_down: 0.01, mix: args.fetch(:sc, 0.8) do
use_synth :bass_foundation
play note - 12, amp: args.fetch(:amp, 0.8), cutoff: get[:chord], res: 0.75
use_synth :bass_highend
play note, amp: args.fetch(:amp, 0.8) * 0.75, drive: 3, cutoff: get[:chord] + 12, res: 0.1, decay: 2.0, sustain_level: args.fetch(:amp, 0.8) * 0.25
end
end
live_loop :snare_clap do
args = sync :drum_snare
pat = args.fetch(:pattern, "--x-")
len = pat.size
tick_reset_all
with_fx :reverb, amp: args.fetch(:amp, 0.5), mix: 0.3, damp: 0.3, room: 0.8 do
with_fx :echo, mix: 1.0, pre_mix: 0.6, phase: 0.75, decay: 1.5, max_phase: 3.0, reps: len do
play = pattern pat
sample :drum_snare_hard, amp: 1.0, pan: 0.05 if play
sample :sn_dolf, amp: 0.75, pan: -0.05 if play
sleep 0.5 if knit(true, len - 1, false, 1).tick(:skip_last)
end
end
end
live_loop :ride do
args = sync :drum_ride
tick_reset_all
pat = args.fetch(:pattern, "x-xxx-x-x-xxx-x-x-xxx-x-x-xxx-x-")
len = pat.size
use_sample_defaults hpf: 54
with_fx :slicer, phase: 1.0, invert_wave: true, wave: 1, pulse_width: 0.05, smooth_up: 0.3, smooth_down: 0.01, mix: args.fetch(:sc, 0.8) do
with_fx :reverb, amp: args.fetch(:amp, 0.5), mix: 0.3, damp: 0.3, room: 0.8 do
with_fx :echo, mix: 1.0, pre_mix: 0.6, phase: 0.75, decay: 1.5, max_phase: 3.0, reps: len do
sample (ring(true, false).tick(:ride) ? :drum_cymbal_hard : :drum_cymbal_soft), amp: rrand(0.9, 1.0), pan: rrand(-0.1, 0.1) if pattern pat
sleep 0.25 if knit(true, len - 1, false, 1).tick(:skip_last)
end
end
end
end
live_loop :acid do
args = sync :tb303_pad
tick_reset_all
pat = args.fetch(:pattern, "---x---x---x---x")
len = pat.size
notes = args.fetch(:notes, ring(get[:chord] + 7, get[:chord] + 14, get[:chord] + 7, get[:chord]))
var = args.fetch(:var, knit(0, 4, 10, 4, 7, 4, 5, 4))
use_synth :tb303
use_synth_defaults wave: 1, release: 0.2, attack: 0.05, decay: 0.1, sustain: 0.2, sustain_level: 0.7, cutoff_sustain_level: 0
with_fx :slicer, phase: 1.0, invert_wave: true, wave: 1, pulse_width: 0.05, smooth_up: 0.4, mix: args.fetch(:sc, 0.8) do
with_fx :reverb, amp: args.fetch(:amp, 0.4), mix: 0.3, damp: 0.3, room: 0.8, reps: len do
with_fx :echo, mix: 1.0, pre_mix: 0.4, phase: 0.75, decay: 3.0, max_phase: 5.0 do
note = notes.tick(:acid_tick) + var.tick(:note_variation)
play note, cutoff: note + 48, cutoff_min: note + 12, cutoff_decay: 0.3, res: (pattern pat) ? 0.9 : 0.4
##| play note, cutoff: note + 48, cutoff_min: (pattern pat) ? note - 12 : note + 12, cutoff_decay: (pattern pat) ? 0.25 : 0.5, res: (pattern pat) ? 0.9 : 0.4
sleep 0.5 if knit(true, len - 1, false, 1).tick(:skip_last)
end
end
end
end
live_loop :ambiance do
args = sync :pad_synth
tick_reset_all
use_synth :hollow
note = args.fetch(:note, get[:chord] + 24)
hollow_chord = args.fetch(:h_chord, [note + 7, note + 14, note + 21])
with_fx :slicer, phase: 1.0, invert_wave: true, wave: 1, pulse_width: 0.05, smooth_up: 0.3, smooth_down: 0.01, mix: args.fetch(:sc, 0.8) do
with_fx :reverb, mix: 0.3, damp: 0, room: 0.8 do
with_fx :hpf, cutoff: note, amp: args.fetch(:amp, 1.0) do
play hollow_chord, attack: 1.0, sustain: args.fetch(:sus, 7.0), release: 3.0, cutoff: note + 24, noise: 3
end
end
end
end
define :amen_bar1_clean_slices do
sample :loop_amen_full, slice: 0, finish: 0.8
sleep 0.5
sample :loop_amen_full, slice: 0, finish: 1.0
sleep 0.5
sample :loop_amen_full, slice: 2, finish: 1.0
sleep 0.5
sample :loop_amen_full, slice: 3, finish: 1.0
sleep 0.5
sample :loop_amen_full, slice: 0, finish: 0.8
sleep 0.5
sample :loop_amen_full, slice: 4, finish: 0.3
sleep 0.25
sample :loop_amen_full, slice: 4, finish: 0.5
sleep 0.25
sample :loop_amen_full, slice: 6, finish: 1.0
sleep 0.5
sample :loop_amen_full, slice: 7, finish: 1.0
sleep 0.4
end
define :play_amen_slices do |slices, rev|
tick_reset_all
beats = slices.size * 4
slices.size.times do
if rev.tick(:rev)
sample :loop_amen_full, slice: slices.tick(:amn_slc), start: rrand(0.75, 1.0), finish: 0
else
sample :loop_amen_full, slice: slices.tick(:amn_slc), finish: rrand(0.9, 1.0)
end
sleep knit(16.0 / beats, beats / 4 - 1, 0, 1).tick(:skip_last)
end
end
live_loop :random_amen do
args = sync :amen_chaos
use_random_seed args.fetch(:seed, rrand_i(0, 1000))
b = args.fetch(:slices, knit(16, 1, 32, 3, 64, 2).choose)
# randomize slices, allow dupes:
if args.fetch(:full, one_in(3))
if args.fetch(:kick, !one_in(3))
slices = ring(0) + range(1, b).repeat(2).pick(b/4-1)
else
slices = range(0, b).repeat(2).pick(b/4)
end
else # only get slices from one bar
bar = args.fetch(:bar, range(0, 4).choose)
if args.fetch(:kick, one_in(2)) and b > 15
slices = ring(0) + range(bar + 1, bar * b/4 + b/4).repeat(2).pick(b/4-1)
else
slices = range(bar * b/4, bar * b/4 + b/4).repeat(2).pick(b/4)
end
end
slices = args[:s_arr] == nil ? slices : args[:s_arr]
# reverse some slices
if args.fetch(:rev, one_in(4))
if one_in(8)
rev = ring(false) + knit(true, 3)
else
rev = ring(false) + knit(false, 3, true, 1).repeat(b/4).pick(b-1)
end
else # don't reverse
rev = ring(false)
end
with_fx :echo, amp: args.fetch(:amp, 0.5), mix: 1.0, pre_mix: 0.28, phase: 0.1875, decay: 1, max_phase: 2.0 do
with_fx :slicer, phase: 0.25, wave: 0, mix: rrand(0.4, 0.7) do
with_fx :bitcrusher, sample_rate: args.fetch(:bc_sr, 11025), bits: args.fetch(:bc_bits, 8) do
use_sample_defaults hpf_sustain_level: 60, hpf_release: 0.2, hpf_release_level: 100, hpf_env_curve: 2, beat_stretch: 16
if args.fetch(:bar1_clean, false)
use_merged_sample_defaults num_slices: 32
amen_bar1_clean_slices
else
use_merged_sample_defaults num_slices: b
play_amen_slices slices, rev
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment