Skip to content

Instantly share code, notes, and snippets.

@jweather
Created April 6, 2015 02:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jweather/b0d2870f1f280dce5a70 to your computer and use it in GitHub Desktop.
Save jweather/b0d2870f1f280dce5a70 to your computer and use it in GitHub Desktop.
Sonic Pi: untitled composition refactored
# based on https://vimeo.com/50061269 by Andrew Sorensen
# refactored and clarified
use_bpm 90
use_synth :dsaw
# five loops, each has a volume from 0 to 1
volumes = [0, 0, 0, 0, 0]
# play a pattern of <notes> with <amps>, with <time> between notes
# use loop index <loop> for the note volumes
# play <count> notes total
# notes and amps should be rings so they can be cycled through
define :pat do |a|
with_fx :reverb do
a[:count].times do |i|
# volume varies randomly around the specified level
variance = rrand(0, 0.1)
play a[:notes][i], amp: volumes[a[:loop]]*(a[:amps][i] + variance),
release: a[:rel] || a[:time]
sleep a[:time]
end
end
end
# all the live loops start at the beginning of the composition,
# but the volumes are turned down initially
# simple two-note pattern with a triplet feel (LA-da-la-DA-la-da, etc.)
# since the rings repeat, this gives 6 notes with:
# note: c4 eb4 c4 eb4 c4 eb4
# amp: .3 .2 .2 .3 .2 .2
# three notes per beat, doodle loops every 4 beats
live_loop :doodle do
pat loop: 0, count: 12,
notes: (ring :c4, :eb4), amps: (ring 0.3, 0.2, 0.2),
time: 1/3.0, rel: 0.45
end
# the other loops all sync on doodle, setting auto_cue:false
# keeps them from creating their own cues, which just clutter up the log
# same two-note pattern, a fifth higher
live_loop :noodle, auto_cue:false do
sync :doodle
pat loop: 1, count: 12,
notes: (ring :g4, :bb5), amps: (ring 0.2, 0.1, 0.1),
time: 1/3.0, rel: 0.4
end
# bass, 8 beats per note
live_loop :boodle, auto_cue:false do
sync :doodle
pat loop: 2, count: 8,
notes: (ring :c4, :bb3, :ab3), amps: (ring 0.35, 0.3, 0.3),
time: 8 if volumes[2] != 0 # don't start playing until we fade in, keeps in sync better
end
# offset bass note, one beat after downbeat
live_loop :foodle, auto_cue:false do
sync :doodle
sleep 1
pat loop: 3, count: 8,
notes: (ring :eb4), amps: (ring 0.4, 0.3, 0.3),
time: 8, rel: 7 if volumes[3] != 0
end
# high arpeg
# triplet feel with six notes per beat
live_loop :arpoodle, auto_cue:false do
sync :doodle
pat loop: 4, count: 24,
notes: (ring :bb5, :eb5, :g6, :eb5, :g6, :eb5), amps: (ring 0.2, 0.1, 0.1),
time: 1/6.0 if volumes[4] != 0
end
# This is still at time=0, all the loops are running, but muted
# fade in each loop, one at a time, in 8 beats per loop
5.times do |loop|
8.times do
volumes[loop] += 1/8.0
puts volumes
sleep 1
end
sleep 16 if loop > 1 # wait some extra time between the longer loops
end
# phase 2
# cycle volumes for each loop separately according to sine curves with different periods
# the periods are primes, meaning the exact pattern doesn't repeat for 7*11*13*17*19 seconds
# which is about 3.75 days
# graph: https://www.desmos.com/calculator/cgxksmsuwk
live_loop :finoodle, auto_cue: false do
factors = [7, 11, 13, 17, 19]
5.times do |loop|
# vt is the current time in beats
volumes[loop] = Math.sin(vt/factors[loop])*0.75 + 1
end
puts volumes
sleep 1
# add some ambience occasionally, almost in key but slightly dissonant
sample :ambi_glass_hum, amp: 0.3, rate: pitch_ratio(3) if one_in(24)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment