Created
January 2, 2018 05:51
-
-
Save amosr/2c8e2c7bc18c5c10e4972aaf1a3b416e to your computer and use it in GitHub Desktop.
sonic pi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# random drum machine | |
# an array of times for when samples should play | |
# we'll have a corresponding array for which | |
# sample to sound at a particular time | |
def times_beat(i) | |
# beats, quarter beats, and triplets | |
times_one = [0, 1.0/4, 1.0/3, 1.0/2.0, 2.0/3, 3.0/4] | |
times_one.map {|j| j + i} | |
end | |
# how likely we are to play a sound at a particular time | |
# the beat is a normal place to play something so 1/4 chance | |
# quarter beat is a little stranger so only 1/7 chance, etc | |
probs_one = [4, 7, 8, 6, 10, 9] | |
# four beats to a bar | |
times = (times_beat 0) + (times_beat 1) + (times_beat 2) + (times_beat 3) | |
probs = probs_one * 4 | |
# lots of samples to choose from | |
sample_choices = [:ambi_choir, :drum_bass_hard, :drum_bass_soft, :drum_cowbell, :drum_cymbal_closed, :drum_cymbal_hard, :drum_snare_hard, :elec_triangle, :elec_snare, :elec_lo_snare, :elec_hi_snare, :elec_mid_snare, :elec_cymbal, :elec_soft_kick, :elec_filt_snare, :elec_fuzz_tom, :elec_chime, :elec_bong, :elec_twang, :elec_wood, :elec_pop, :elec_beep, :elec_blip, :elec_blip2, :elec_ping, :elec_bell, :elec_flip, :elec_tick, :elec_hollow_kick, :elec_twip, :elec_plip, :elec_blup] | |
# start off with no samples playing, nil for each time | |
# as the loop runs we will modify this a bit | |
# but each loop will be based on the previous to give some kind of development | |
samples = [nil] * times.length | |
live_loop :drummer do | |
# cool sounds need cool effects | |
with_fx :krush do | |
with_fx :flanger, feedback: 0.5 do | |
with_fx :slicer, phase: 0.25 do | |
prev = 0 | |
# see what samples are currently playing | |
active = samples.select {|i| i != nil} | |
# play one bar, mutating the drum pattern as we go | |
times.length.times do |i| | |
# figure out how long we need to wait based on | |
# when we last played a note | |
at = times[i] | |
sleep (at - prev) | |
prev = at | |
# modify the pattern at this time before playing it | |
# turn off the sample sometimes | |
# we don't want the pattern to get too crowded. | |
# if we have many active notes, make it more likely to kill some | |
if one_in (times.length - active.length) | |
samples[i] = nil | |
end | |
# should we play a note at this time? | |
# if so, turn on the sample | |
if one_in probs[i] | |
# we have a lot of samples we could choose, | |
# but the pattern shouldn't go too crazy. | |
# choose one of the active samples to introduce consistency | |
if one_in 2 and active.length > 1 | |
samples[i] = active.choose | |
else | |
samples[i] = sample_choices.choose | |
end | |
end | |
# play the thing | |
sample samples[i] if samples[i] | |
end | |
# sleep until the start of the next bar | |
sleep (prev.ceil - prev) | |
end | |
end | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ch = scale :c1, :aeolian, num_octaves: 2 | |
print ch | |
n = 8 | |
def lcm_scaled(a, b) | |
big = 12 | |
lcm = (a * big).round.lcm (b * big).round | |
return lcm / big | |
end | |
def harmony(root,harmon) | |
diff = (harmon - root) % 12 | |
freq = 2**(diff / 12.0) | |
lcm = lcm_scaled 1, freq | |
return lcm | |
end | |
lengths = [0.25, 0.5, 0.25, 0.25, 0.25, 0.5, 0.125, 0.125, 0.25, 0.33333, 0.33333].ring | |
rests = [false, true, true, true, true, true, true].ring | |
live_loop :bass do | |
use_synth :dsaw | |
with_fx :slicer, phase: 0.25 do | |
with_fx :krush, amp: 4 do | |
total = 0 | |
while true | |
l = lengths.tick :lengths | |
r = rests.tick :rests | |
if total + l > 1 | |
break | |
end | |
if not r then | |
play ch[n], sustain: (l * 0.5) | |
end | |
sleep l | |
total += l | |
end | |
print total | |
sleep (total.ceil - total) | |
root = ch[0] | |
n_new = n | |
(-4.upto 4).each do |jump| | |
prob = harmony root, ch[n+jump] | |
if jump != 0 and one_in (prob + jump.abs) | |
n_new = n + jump | |
end | |
end | |
n = n_new | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice