Hi there,
I’d like to share with you one of the first things I did in Sonic Pi. It’ll play for about 5 minutes before it stops. Not very engaging music, but nice in the background.
# Made 2025-03-09
define :play_complex do |n, v|
return if n == -1
weight_on_lower = (0.8)**((n-69)/12) # extra weight on duration(release) and velocity in lower octaves
release = weight_on_lower*1.66
vel = v+0.1*rrand(0, 1)
amp1 = 0.1*weight_on_lower*(0.5+vel)
amp2 = amp1*(0.1+0.7*vel)
amp3 = amp2*(0.1+0.5*vel)
# each note is made into a complex: base-note and octave doubled with added octaves and higher 5ths
notes = [n-0.05, n+0.05, n+12+0.02, n+12-0.02, n+19, n+24, n+36, n+43]
amps = [amp1, amp1, amp2, amp2, amp3, amp3*0.5, 0.05*amp1*(0.7+vel), 0.02*amp1*(0.1+vel)]
rel_release = [1, 1, 0.8, 0.8, 0.5, 0.4, 0.1, 0.02]
pans = [-1, 1, -1, 1, -0.5, 0.5, -0.2, 0.2]
notes.each_with_index do |note, i|
play note, amp: amps[i], pan: pans[i], release: rel_release[i]*release
end
end
define :play_and_sprout do |s, n, v, r|
return if v < 0.012
in_thread do
play_complex n, v
# more rythmic timing
sleep (1+rand_i(3))*0.5*s
# more dreamy timing
# sleep (1+rrand(0, 2)*0.5)*s
offspring = dice(6) < 6 ? 1 : 2 # sometimes sprout two notes
offspring.times do
next_chord_note = (chord r+12*[0,0,0,0,0,0,1,1,2].choose, :major).choose
next_alt_note = (chord n + 12 * 12 * [0, 0, 0, 1].choose, :major).choose
n_next = dice(12) < 12 ? next_chord_note : next_alt_note
v_next = dice(10) < 10 ? 0.5*v : 1.4*v
v_next = 0.9 if v_next > 0.9
play_and_sprout s, n_next, v_next, r
end
end
end
chords = [:c2, :c3, :g3, :f3, :c3, :f2, :g2, :c3]
song_arc = [0.0, 0.2, 0.5, 0.7, 0.8, 0.7, 0.9, 0.3, 0.1, 0.0]
with_fx :gverb, room: 30 do
use_bpm 96
loop do
bars_per_chord = 2
root = chords.ring[tick/bars_per_chord]
pt = chords.length*bars_per_chord # define tempo of progression for calculating progression in arc
arc_vel = (song_arc[look/pt]*(pt-look%pt) + song_arc[look/pt+1]*(look%pt))/pt # no ring. song will end automatically
play_and_sprout 1, root, 0.4*arc_vel, root
sleep 2
play_and_sprout 0.5, root+7, 0.33*arc_vel, root
sleep 2
end
end
I like how it is both random, as well as adhering to an idea of what the song should be like.
When it plays, some dissonant notes appear. No doubt because of the way the source for next_alt_note
is picked. One can make the creation of this more consonant, but I quite like the fact some of these weird notes pop up.
The play_complex
-function was inspired by a tune on dittytoy.net (the site that set me onto Sonic Pi).
As a programmer I notice that there are a lot of parameters, magic values if you like.
Love to hear you feedback