Skip to content

Instantly share code, notes, and snippets.

@KHN190
Last active December 31, 2025 18:38
Show Gist options
  • Select an option

  • Save KHN190/50aebd022f64ebd5967f23f20affcb7b to your computer and use it in GitHub Desktop.

Select an option

Save KHN190/50aebd022f64ebd5967f23f20affcb7b to your computer and use it in GitHub Desktop.
Sonic Pi music.
use_debug false
use_midi_logging true
set :n_density, 0
live_loop :density_tracker do
current = get(:n_density)
set :n_density, [current - 1, 0].max
sleep 0.2
end
def n(root)
note(root)
end
def M3(root)
[n(root), n(root) + 4, n(root) + 7]
end
def m3(root)
[n(root), n(root) + 3, n(root) + 7]
end
def Mm4(root)
# return [a,b,c,d], abc is M3 and bcd is m3
[n(root), n(root) + 4, n(root) + 7, n(root) + 11]
end
def M3_Octave(root)
# [M3] + octave
[n(root), n(root) + 4, n(root) + 7, n(root) + 12]
end
def overtone(note, amp)
chord_fn = [:M3, :m3].choose
chords = send(chord_fn, note)
num = rrand(1, 2)
added_notes = chords.drop(1).first(num)
notes = [note] + (added_notes || [])
density = get(:n_density) || 0
df = [1.0 - (density * 0.05), 0.8].max
# play notes with slight delay
# amp decay for added notes
t = 0
notes.each_with_index do |n, i|
vol = amp * (0.05 ** i) * 2
at t do
play n, amp: vol, sustain: 0.5 * df, release: 0.5 * df
end
t += rand(0.02..0.04)
end
end
def pat(s)
return s.ring.tick == "x"
end
# play all, loop pattern, loop amp
def auto_pat(notes, pstr, speed=0.25, amp=1)
idx = 0
while idx < notes.length do
if pat pstr
keys = notes[idx]
vol = amp.kind_of?(Array) ? amp.ring[idx] : amp
keys = [keys] if !keys.kind_of?(Array)
keys.each do |k| overtone(k, vol) end
set :n_density, (get(:n_density) || 0) + keys.length
idx += 1
end
sleep speed
end
end
def get_kurd_map(root)
{
:D => root - 7,
1 => root,
2 => root + 1,
3 => root + 3,
4 => root + 5,
5 => root + 7,
6 => root + 8,
7 => root + 10,
8 => root + 12,
9 => root + 15
}
end
$k45 = get_kurd_map(45)
$k57 = get_kurd_map(57)
def n_kurd(key, map = $k45)
if key.kind_of?(Array)
return key.map { |k| n_kurd(k, map) }
end
return map[key] if map.has_key?(key)
return 0
end
# '[1,3]x2,5x4,[3,5],1,3,5'
def kurds(str, map = $k45)
str.gsub(/\s+/, "").scan(/\[[^\]]+\](?:x\d+)?|[^,]+/).flat_map do |t|
if m = t.match(/^(.*)x(\d+)$/)
v, c = m[1], m[2].to_i
else
v, c = t, 1
end
if v.start_with?('[')
item = v[1..-2].split(',').map { |k| n_kurd(k.match?(/^\d+$/) ? k.to_i : k.delete(':').to_sym, map) }
else
item = n_kurd(v.match?(/^\d+$/) ? v.to_i : v.delete(':').to_sym, map)
end
[item] * c
end.ring
end
live_loop :appregio do
##| stop
use_synth :pluck
with_fx :eq, mix: 1, low: 1.2, high: 1.2 do
2.times do
notes = kurds(([1,4,6] * 2).join(','))
auto_pat(notes, 'xxx', 0.2, amp=[0.6,0.8,0.8])
notes = kurds(([2,4,6] * 2).join(','))
auto_pat(notes, 'xxx', 0.2, amp=[0.8,1,1])
end
2.times do
notes = kurds(([1,6]*4+[2,6]*4).join(','))
auto_pat(notes, 'xx', 0.4, amp=[0.8,1])
end
notes = kurds(([4,8]*4+[3,8]*4+[5,8]*3+[7,8]+[6,8]*3+[7,8]).join(','))
auto_pat(notes, 'xx', 0.4, amp=[0.8,1])
notes = kurds('[3,5],5x4, [4,6],6x4, [2,6],4x4, [1,4],4x4',map=$k57)
auto_pat(notes, 'x-xx-xx-', 0.2, amp=([1]+[0.8]*4))
notes = kurds('[3,5]x5, [4,6]x5, [5,7]x5, [2,4]x5, [1,4]x5',map=$k57)
auto_pat(notes, 'x-xx-xx-', 0.2, amp=([1]+[0.8]*4))
sleep 0.5
notes = kurds('[3,5]x5, [4,6]x5, [5,7]x5, [2,4]x5') # [1,4]x5 to end
auto_pat(notes, 'x-xx-xx-', 0.2)
sleep 0.5
notes = kurds(([[3,7],5,3]*2 +[8,6,3]*2).join(','),map=$k57)
auto_pat(notes, 'x-xx'+'x'*6, 0.2, amp=[1,0.8,0.6,0.8])
sleep 0.5
notes = kurds(([[2,4],6,4]*2 +[8,4,2]*2).join(','),map=$k57)
auto_pat(notes, 'x-xx'+'x'*6, 0.2, amp=[1,0.8,0.6,0.8])
sleep 0.5
##| THE END
notes = kurds('[3,5]x5, [4,6]x5, [5,7]x5, [2,4]x5, [1,4]x5')
auto_pat(notes, 'x-xx-xx-', 0.2)
end
sleep 2
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment