Skip to content

Instantly share code, notes, and snippets.

@ltlian
Last active October 24, 2022 23:25
Show Gist options
  • Save ltlian/4c59f7cafa12c9015a5e68cbc08ccc3a to your computer and use it in GitHub Desktop.
Save ltlian/4c59f7cafa12c9015a5e68cbc08ccc3a to your computer and use it in GitHub Desktop.
Generative music with Sonic PI
# Read more about Sonic PI:
# https://sonic-pi.net/
# https://github.com/sonic-pi-net
BEGIN {
use_random_seed 0
set_link_bpm! 100
root_1 = :c2
root_2 = :gs1
root_3 = :as1
key_1 = [:c, :d, :ds, :f, :g, :as]
key_2 = [:ds, :gs, :c, :as]
key_3 = [:c, :d, :ds, :f]
chord_1 = [:c4, :g4, :c5, :ds5]
chord_2 = [:gs4, :ds4, :gs4, :c4]
chord_3 = [:as4, :f4, :as4, :d4]
notes_1 = note_range root_1 + 48, root_1 + 60, pitches: key_1
notes_2 = note_range root_2 + 48, root_2 + 60, pitches: key_2
notes_3 = note_range root_3 + 48, root_3 + 60, pitches: key_3
times = []
while times.sum <= 12 do
times.append(choose([0.25, 0.25, 0.5, choose([1, 2, 3, 4])]))
end
set :key, key_1
set :chords, chord_1
set :times, times
set :root, root_1
}
in_thread do
live_loop :main do
link 16
set :key, key_1
set :chords, chord_1
set :lead, notes_1.pick(times.count)
set :root, root_1
set :segment, tick
sleep 12
link 16
set :key, key_1
set :chords, chord_1
set :lead, notes_1.pick(times.count)
set :root, root_1
set :segment, tick
sleep 12
link 16
set :key, key_2
set :chords, chord_2
set :lead, notes_2.pick(times.count)
set :root, root_2
set :segment, tick
sleep 12
link 16
set :key, key_3
set :chords, chord_3
set :lead, notes_3.pick(times.count)
set :root, root_3
set :segment, tick
sleep 12
end
end
in_thread do
live_loop :bass do
with_synth :bass_foundation do
root = sync :root
in_thread do
4.times do
play root, sustain: 1, amp: 0.5
sleep 4
end
end
end
end
end
in_thread do
live_loop :perc do
sync :segment
in_thread do
4.times do
perc_bar()
link
end
end
end
end
def perc_bar()
sample :drum_bass_soft, amp: 0.7
sleep 0.5
sample :drum_bass_soft, amp: 0.3
sleep 0.5
sample :drum_cymbal_closed
sample :drum_snare_soft, amp: 0.7
sleep 0.75
sample :drum_bass_soft, amp: 0.3
sleep 0.25
sample :drum_cymbal_closed
sample :drum_bass_soft, amp: 0.7
sleep 0.5
sample :drum_bass_soft, amp: 0.3
sleep 0.5
sample :drum_cymbal_closed
sample :drum_snare_soft, amp: 0.7
sleep 0.5
sample :drum_bass_soft, amp: 0.3
end
in_thread do
with_synth :subpulse do
with_fx :ping_pong, phase: 0.75, pan_start: 0.75 do
live_loop :arp do
use_octave 3
note = choose(note_range get[:root], get[:root] + 15, pitches: get[:key])
mod = [(beat % 16) - ((get[:segment] || 0) + 8), 0].max / choose([8, 10])
play note, amp: rrand(0.2, 0.8 - [mod, 0.8].min), release: 0.2 + mod
sleep choose([1.5, 2.5])
link 1
end
end
end
end
in_thread do
with_synth :tech_saws do
with_fx :ping_pong, phase: 0.2, max_phase: 3, pan_start: 0.75 do
live_loop :chords do
with_fx :reverb do
with_fx :flanger do
chords = sync :chords
play_chord chords, attack: 2, release: 7, amp: 0.4
end
end
end
end
end
end
def get_chord (note, key)
if key.nil?
[note]
else
rng = (note_range :c6, :c7, pitches: key)
idx = rng.index(note + 0)
if idx.nil?
[note]
elsif one_in 3
[note, rng[idx + 1]]
elsif one_in 2
[rng[idx - 2], note, rng[idx + 1]]
else
[rng[idx - 2], note]
end
end
end
in_thread do
with_synth :blade do
with_fx :ping_pong, phase: 0.75, max_phase: 3, mix: 0.33 do
live_loop :lead_in do
use_octave -2
lead = sync :lead
if one_in 3
shuffle = choose([0.25, 0])
sleep 15 + shuffle * 2
l = play choose(lead), sustain: 0.75 - choose([0, shuffle]), release: 0.1, amp: rrand(0.4, 1)
sleep 0.5 - shuffle
control l, note: choose(lead)
end
end
live_loop :lead do
use_octave -2
lead = sync :lead
in_thread do
get[:times].each_with_index do |t, i|
if one_in 4
play lead[i], sustain: t, release: 0.1, amp: rrand(0.4, 1)
elsif one_in 2
# ghost
elsif one_in 2
play lead[i], release: 0.5, decay: 0, amp: rrand(0.4, 1)
else
play lead[i], release: 1, decay: 0, amp: rrand(0.4, 1)
end
sleep t
end
end
end
end
end
end
in_thread do
with_synth :winwood_lead do
with_fx :ping_pong, phase: 0.75, max_phase: 3, mix: 0.33, amp: 0.35 do
live_loop :lead_canon do
use_octave -2
lead = sync :lead
key = get[:key]
root = get[:root]
in_thread do
get[:times].each_with_index do |t, i|
on 4 < i && i < choose([9, 12]) do
with_swing 2, 1 do
canon = get_chord(lead[i], key)
play_chord(canon, sustain: choose([0.1, 0.2, t]), release: 0.1, ramp_ratio: 0)
end
end
sleep t
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment