Skip to content

Instantly share code, notes, and snippets.

@interstar
Created April 6, 2021 15:13
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 interstar/6078dfb434c318997fe510536f246161 to your computer and use it in GitHub Desktop.
Save interstar/6078dfb434c318997fe510536f246161 to your computer and use it in GitHub Desktop.
Sonic Pi chord progression generator (now with modal interchange, secondary dominants AND INVERSIONS)
# MIDI Chord generation
# Now with modal interchange, secondary dominants & inversions
# See https://www.youtube.com/watch?v=3yryQbRgsGo
define :oneChord do | tonic, mode, deg |
majorKeyTriads = [:M,:m,:m,:M,:M,:m,:dim]
minorKeyTriads = [:m,:dim,:M,:m,:m,:M,:M]
majorKey7s = [:M7,:m7,:m7,:M7,:dom7,:m7,:halfdiminished]
minorKey7s = [:m7,:halfdiminished,:M7,:m7,:m7,:M7,:dom7]
# First test if deg is actually an array.
# Because if it is, this is a more complex chord item
if deg.class == Array then
# Representation here is [chord-deg, inversion]
# chord-deg is understood as degree to calculate chord,
# inversion is 1 (first inversion), 2 (2nd inversion),
# -1 (first inversion and drop an octave
# -2 (second inversion and drop an octave)
t,m,c = oneChord(tonic,mode,deg[0])
case deg[1]
when 0
newChord = c
when 1
newChord = c[1..10]+[c[0]+12]
when 2
newChord = c[2..10]+[c[0]+12]+[c[1]+12]
when 3
newChord = c[3..10]+[c[0]+12]+[c[1]+12]+[c[2]+12]
when -1
newChord = (c[1..10]+[c[0]+12]).map {|n| n-12 }
when -2
newChord = (c[2..10]+[c[0]+12]+[c[1]+12]).map {|n| n - 12}
when -3
newChord = (c[3..10]+[c[0]+12]+[c[1]+12]+[c[2]+12]).map {|n| n - 12}
else
newChord = c
end
return [t,m,newChord]
end
# Modal interchange (negative numbers major <-> minor)
if deg < 0 then
return oneChord(tonic,(mode=="major") ? "minor" : "major",-deg)
end
case deg
when 1..7 # Simple Triads
root = degree(deg,tonic,mode)
lookup = (mode == "major") ? majorKeyTriads : minorKeyTriads
theChord = chord(root,lookup[deg-1])
when 71..77 # Seventh Chords
deg = deg - 70
root = degree(deg,tonic,mode)
lookup = (mode == "major") ? majorKey7s : minorKey7s
theChord = chord(root,lookup[deg-1])
when 21..27 # Secondary dominants
deg = deg - 20
original_root = degree(deg,tonic,mode)
root = degree(5,original_root,mode)
theChord = chord(root,:dom7)
tonic = root
end
return [tonic,mode,theChord]
end
define :chordSeq do | tonic, mode, degs |
cs = []
degs.each { | deg |
xs = oneChord(tonic,mode,deg)
cs.append(xs)
}
cs
end
use_bpm 100
with_fx :reverb do
with_synth :piano do
live_loop :piano do
cs = chordSeq(:C4,"major",[71,[75,-2],[76,-1],74])
cs.each { |xs|
t,m,c = xs
c.each {|cn|
midi cn, 90, channel: 1,
port: "loopbe_internal_midi_1"
sleep 0.6
}
c.each {|cn| midi_note_on cn, 90, channel: 1,
port: "loopbe_internal_midi_1" }
sleep 0.4
c.each {|cn| midi_note_off cn, channel: 1,
port: "loopbe_internal_midi_1" }
sleep 0.2
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment